package main;

import com.primavera.ServerException;
import com.primavera.integration.client.bo.BOIterator;
import com.primavera.integration.client.bo.BusinessObjectException;
import com.primavera.integration.client.bo.object.User;
import com.primavera.integration.network.NetworkException;
import main.Link.*;
import main.Primavera.LoginFunctions;
import main.Primavera.ProjectConfig;
import main.SQL.*;
import main.SQL.objects.SQLDocumentStructure;
import main.Trees.ProjectNode;
import main.Trees.SmetNode;
import main.Trees.SmetTreeModel;
import main.components.StatusBar;
import main.dialogs.LoginDialog;
import main.reports.CheckSmetReport;

import main.reports.SelectProjectDialog;
import main.synch.PrimaveraProject;
import main.synch.SynchThread;
import main.synch.UpdateProjectRaThread;
import main.synch.ValidThread;
import main.users.UsersDialog;
import org.jdesktop.swingx.JXTreeTable;
import org.jdesktop.swingx.decorator.*;

import javax.imageio.ImageIO;
import javax.swing.*;
import javax.swing.event.ListSelectionEvent;
import javax.swing.event.ListSelectionListener;
import javax.swing.event.TreeSelectionEvent;
import javax.swing.event.TreeSelectionListener;
import javax.swing.plaf.basic.BasicSplitPaneUI;
import javax.swing.table.DefaultTableModel;
import javax.swing.tree.DefaultTreeModel;
import javax.swing.tree.TreeNode;
import javax.swing.tree.TreePath;
import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.io.IOException;
import java.sql.*;
import java.util.ArrayList;
import java.util.Enumeration;
import java.util.HashMap;

public class MainApp extends javax.swing.JFrame {
    public static LoginFunctions loginFunc;
    private OpenProjectDialog op;
    private Object[] colNames = {"ID", "Наименование ресурса", "Кол-во", "Тип ресурса"};
    private SmetTreeModel smetStructureTreeModel;
    private LinkTable linkTM;
    public static SQLProjectModel projectStructureModel;
    public static ProjectNode curProject;
    public static LinkArray linkTableArray;
    public static HashMap<String, SQLRsrc> rsrcMap;
    public String row;
    private Connection connSQL;
    private int findRow;

    //region Настройки проекта
    private ProjectConfig projectConfig;
    //endregion

    public static HashMap<String, SmetNode> allSmrMap = new HashMap<>();
    public static HashMap<Integer, ProjectNode> taskMap;
    public static HashMap<String, HashMap<Integer, SQLLink>> linkSmrMap;
    public static SQLDocumentStructure docStructure;

    //region MainApp() - конструктор, инициализация формы программы, вызов из FactageApp.main()
    public MainApp() {
        initComponents();
        centerOnScreen(this);
        initStatusBar();

        smetStructureTreeModel = new SmetTreeModel();
        smetStructureTree.setTreeTableModel(smetStructureTreeModel);
        smetStructureTree.setRootVisible(true);
        smetStructureTree.setSortable(true);
        initSmetTree();

        initLinkTable();
        initTaskRsrcTable();

        linkTableArray = null;

        linkFrame.pack();
        openSmetDialog.pack();
        //synchProject();

    }
    //endregion

    //region Блок. Методы инициализации

    //region initTaskRsrcTable() - форматирование таблицы ресурсов работ, вызов из MainApp()
    private void initTaskRsrcTable() {
        taskRsrcTable.setShowGrid(true);
        taskRsrcTable.setRowHeight(20);
        taskRsrcTable.setGridColor(new Color(219, 219, 219));

        if (taskRsrcTable.getColumnModel().getColumnCount() > 0) {
            taskRsrcTable.getColumnModel().getColumn(0).setMinWidth(40);
            taskRsrcTable.getColumnModel().getColumn(0).setPreferredWidth(70);
            taskRsrcTable.getColumnModel().getColumn(0).setMaxWidth(100);
            taskRsrcTable.getColumnModel().getColumn(2).setMinWidth(40);
            taskRsrcTable.getColumnModel().getColumn(2).setPreferredWidth(70);
            taskRsrcTable.getColumnModel().getColumn(2).setMaxWidth(100);
            taskRsrcTable.getColumnModel().getColumn(3).setMinWidth(40);
            taskRsrcTable.getColumnModel().getColumn(3).setPreferredWidth(100);
            taskRsrcTable.getColumnModel().getColumn(3).setMaxWidth(150);
        }
    }
    //endregion

    //region initStatusBar() - инициализация статус-бара, вызов из MainApp()
    private void initStatusBar() {

    }
    //endregion

    //region setIcon() - установка иконки окна, вызов из FactageApp.main()
    public void setIcon() {
        try {
            Image iconTask = ImageIO.read(getClass().getResource("images/f_ck1.png"));
            this.setIconImage(iconTask);
        } catch (IOException e) {
            e.printStackTrace();
        }

    }
    //endregion

    //region initLinkTable() - инициализация таблицы связей, вызов из MainApp()
    private void initLinkTable() {

        linkTable.setShowGrid(true);
        linkTable.setRowHeight(25);
        linkTable.setGridColor(new Color(219, 219, 219));

        if (linkTable.getColumnModel().getColumnCount() > 0) {
            linkTable.getColumnModel().getColumn(0).setMinWidth(20);
            linkTable.getColumnModel().getColumn(0).setPreferredWidth(50);
            linkTable.getColumnModel().getColumn(0).setMaxWidth(70);
            linkTable.getColumnModel().getColumn(2).setMinWidth(20);
            linkTable.getColumnModel().getColumn(2).setPreferredWidth(130);
            linkTable.getColumnModel().getColumn(2).setMaxWidth(150);
            linkTable.getColumnModel().getColumn(3).setMinWidth(20);
            linkTable.getColumnModel().getColumn(3).setPreferredWidth(30);
            linkTable.getColumnModel().getColumn(3).setMaxWidth(50);
            linkTable.getColumnModel().getColumn(5).setMinWidth(20);
            linkTable.getColumnModel().getColumn(5).setPreferredWidth(50);
            linkTable.getColumnModel().getColumn(5).setMaxWidth(70);
            linkTable.getColumnModel().getColumn(7).setMinWidth(20);
            linkTable.getColumnModel().getColumn(7).setPreferredWidth(30);
            linkTable.getColumnModel().getColumn(7).setMaxWidth(50);
            linkTable.getColumnModel().getColumn(8).setMinWidth(20);
            linkTable.getColumnModel().getColumn(8).setPreferredWidth(50);
            linkTable.getColumnModel().getColumn(8).setMaxWidth(70);
            linkTable.getColumnModel().getColumn(9).setMinWidth(20);
            linkTable.getColumnModel().getColumn(9).setPreferredWidth(30);
            linkTable.getColumnModel().getColumn(9).setMaxWidth(50);

            linkTable.getColumnModel().getColumn(0).setCellRenderer(new CellRendererColorOther(row));
            linkTable.getColumnModel().getColumn(1).setCellRenderer(new CellRendererTextArea(row));
            linkTable.getColumnModel().getColumn(2).setCellRenderer(new CellRendererTextArea(row));
            linkTable.getColumnModel().getColumn(3).setCellRenderer(new CellRendererColorOther(row));
            linkTable.getColumnModel().getColumn(4).setCellRenderer(new CellRendererTextArea(row));
            linkTable.getColumnModel().getColumn(5).setCellRenderer(new CellRendererColorOther(row));
            linkTable.getColumnModel().getColumn(6).setCellRenderer(new CellRendererColorOther(row));
            linkTable.getColumnModel().getColumn(7).setCellRenderer(new CellRendererColorFactor(row));
            linkTable.getColumnModel().getColumn(8).setCellRenderer(new CellRendererColorFactor(row));
            linkTable.getColumnModel().getColumn(9).setCellRenderer(new CellRendererColorCheckBox(row));
        }
    }
    //endregion

    //region initProjectTree() - инициализация дерева проектов?
    private void initProjectTree() {

//        projectStructureTree.getTableHeader().setDefaultRenderer(new TreeHeaderRenderer());
//        projectStructureTree.getTableHeader().setPreferredSize(new Dimension(30,30));
//        projectStructureTree.setBorder();
        try {
            Image iconTask = ImageIO.read(getClass().getResource("images/task.png"));
            projectStructureTree.setLeafIcon(new ImageIcon(iconTask));
            Image iconWbs = ImageIO.read(getClass().getResource("images/wbs.png"));
            projectStructureTree.setOpenIcon(new ImageIcon(iconWbs));
            projectStructureTree.setClosedIcon(new ImageIcon(iconWbs));
        } catch (IOException e) {
            e.printStackTrace();
        }
//Pink color theme
//        PatternPredicate leafPr = new PatternPredicate(".", 3);
//        ColorHighlighter leafs = new ColorHighlighter(leafPr, Color.white, null, null, null);
//        PatternPredicate rootPr = new PatternPredicate("ROOT", 1);
//        ColorHighlighter rootHL = new ColorHighlighter(rootPr, new Color (216,112,147), Color.white, null, null);
//        PatternPredicate wbsPr0 = new PatternPredicate("WBS0", 1);
//        ColorHighlighter wbsHL0 = new ColorHighlighter(wbsPr0, new Color (220,137,167), Color.white, null, null);
//        PatternPredicate wbsPr1 = new PatternPredicate("WBS1", 1);
//        ColorHighlighter wbsHL1 = new ColorHighlighter(wbsPr1, new Color (225,161,186), Color.white, null, null);
//        PatternPredicate wbsPr2 = new PatternPredicate("WBS2", 1);
//        ColorHighlighter wbsHL2 = new ColorHighlighter(wbsPr2, new Color (229,186,206), Color.black, null, null);
//        PatternPredicate wbsPr3 = new PatternPredicate("WBS3", 1);
//        ColorHighlighter wbsHL3 = new ColorHighlighter(wbsPr3, new Color (233,211,226), Color.black, null, null);
//        PatternPredicate wbsPr4 = new PatternPredicate("WBS4", 1);
//        ColorHighlighter wbsHL4 = new ColorHighlighter(wbsPr4, new Color (238,236,245), Color.black, null, null);

//        PatternPredicate leafPr = new PatternPredicate(".", 3);
//        ColorHighlighter leafs = new ColorHighlighter(leafPr, Color.white, null, null, null);
//        PatternPredicate rootPr = new PatternPredicate("ROOT", 1);
//        ColorHighlighter rootHL = new ColorHighlighter(rootPr, new Color (68,153,177), Color.white, new Color(177, 142, 118), Color.white);
//        PatternPredicate wbsPr0 = new PatternPredicate("WBS0", 1);
//        ColorHighlighter wbsHL0 = new ColorHighlighter(wbsPr0, new Color (78,160,187), Color.white, new Color(188, 145, 109), Color.white);
//        PatternPredicate wbsPr1 = new PatternPredicate("WBS1", 1);
//        ColorHighlighter wbsHL1 = new ColorHighlighter(wbsPr1, new Color (95,173,196), Color.white, new Color(199, 149, 100), Color.white);
//        PatternPredicate wbsPr2 = new PatternPredicate("WBS2", 1);
//        ColorHighlighter wbsHL2 = new ColorHighlighter(wbsPr2, new Color (113,187,207), null, new Color(210, 152, 90), Color.white);
//        PatternPredicate wbsPr3 = new PatternPredicate("WBS3", 1);
//        ColorHighlighter wbsHL3 = new ColorHighlighter(wbsPr3, new Color (132,203,221), null, new Color(210, 152, 90), Color.black);
//        PatternPredicate wbsPr4 = new PatternPredicate("WBS4", 1);
//        ColorHighlighter wbsHL4 = new ColorHighlighter(wbsPr4, new Color (152,216,227), null, new Color(232, 158, 72), Color.black);
//
//        PatternPredicate wbsPr5 = new PatternPredicate("WBS5", 1);
//        ColorHighlighter wbsHL5 = new ColorHighlighter(wbsPr4, new Color (211,181,144), Color.black, new Color(232, 158, 72), Color.black);
//
//        ColorHighlighter greyFont = new ColorHighlighter(new HighlightPredicate.ColumnHighlightPredicate(5, 6), null, Color.gray, null, Color.gray);
//
//        Highlighter stripeHL = HighlighterFactory.createSimpleStriping(new Color (242,242,242), 1);
//
//        PatternPredicate linkSmetToWork = new PatternPredicate("true", 7);
//        ColorHighlighter lstw = new ColorHighlighter(linkSmetToWork, new Color(229, 182, 255), null, new Color(241, 159, 128), null);
//        PatternPredicate taskUse = new PatternPredicate("true", 8);
//        ColorHighlighter tu = new ColorHighlighter(taskUse, new Color(188, 255, 188), null, new Color(221, 195, 94), null);
//
//        projectStructureTree.setSelectionBackground(new Color(255, 195, 128));
//        projectStructureTree.setSelectionForeground(null);
//
//        Highlighter hl = new FontHighlighter(new HighlightPredicate.ColumnHighlightPredicate(0, 4, 5, 6), new Font(null, Font.PLAIN, 9));
//
//        Highlighter rootFont = new FontHighlighter(rootPr, new Font(null, Font.PLAIN, 14));
//
//        projectStructureTree.setHighlighters(leafs, stripeHL, wbsHL0, wbsHL1, wbsHL2, wbsHL3, wbsHL4, rootHL, rootFont, tu, lstw, hl, greyFont);
//
//        projectStructureTree.setRowHeight(20);
//        //projectStructureTree.setGridColor(new Color(232, 220, 207));
//        projectStructureTree.setGridColor(new Color(216,225,227));
//        projectStructureTree.setShowGrid(false, true);

        PatternPredicate leafPr = new PatternPredicate(".", 3);
        ColorHighlighter leafs = new ColorHighlighter(leafPr, Color.white, null, null, null);
        PatternPredicate rootPr = new PatternPredicate("ROOT", 1);
        ColorHighlighter rootHL = new ColorHighlighter(rootPr, new Color (100,149,237), Color.white, new Color(177, 142, 118), Color.white);
        PatternPredicate wbsPr0 = new PatternPredicate("WBS0", 1);
        ColorHighlighter wbsHL0 = new ColorHighlighter(wbsPr0, new Color (122,155,218), Color.white, new Color(188, 145, 109), Color.white);
        PatternPredicate wbsPr1 = new PatternPredicate("WBS1", 1);
        ColorHighlighter wbsHL1 = new ColorHighlighter(wbsPr1, new Color (144,162,200), Color.white, new Color(199, 149, 100), Color.white);
        PatternPredicate wbsPr2 = new PatternPredicate("WBS2", 1);
        ColorHighlighter wbsHL2 = new ColorHighlighter(wbsPr2, new Color (167,168,181), Color.black, new Color(210, 152, 90), Color.white);
        PatternPredicate wbsPr3 = new PatternPredicate("WBS3", 1);
        ColorHighlighter wbsHL3 = new ColorHighlighter(wbsPr3, new Color (189,174,163), Color.black, new Color(210, 152, 90), Color.black);
        PatternPredicate wbsPr4 = new PatternPredicate("WBS4", 1);
        ColorHighlighter wbsHL4 = new ColorHighlighter(wbsPr4, new Color (211,181,144), Color.black, new Color(232, 158, 72), Color.black);
        PatternPredicate linkSmetToWork = new PatternPredicate("true", 7);
        ColorHighlighter lstw = new ColorHighlighter(linkSmetToWork, new Color(229, 182, 255), Color.black, new Color(241, 159, 128), Color.black);
        PatternPredicate taskUse = new PatternPredicate("true", 8);
        ColorHighlighter tu = new ColorHighlighter(taskUse, new Color(188, 255, 188), Color.black, new Color(221, 195, 94), Color.black);

        projectStructureTree.setSelectionBackground(new Color(255, 195, 128));
        projectStructureTree.setSelectionForeground(Color.black);

        //Highlighter rootFont = new FontHighlighter(rootPr, new Font(null, Font.PLAIN, 14));
        projectStructureTree.setHighlighters(leafs, wbsHL0, wbsHL1, wbsHL2, wbsHL3, wbsHL4, rootHL, tu, lstw);

        projectStructureTree.setRowHeight(20);
        projectStructureTree.setGridColor(new Color(232, 220, 207));
        projectStructureTree.setShowGrid(true, true);

        projectStructureTree.addTreeSelectionListener(new TreeSelectionListener() {
            @Override
            public void valueChanged(TreeSelectionEvent treeSelectionEvent) {
                highlightSmRows();
            }
        });
        projectStructureTree.setSortsOnUpdates(true);
        projectStructureTree.setSortOrder(0, SortOrder.ASCENDING);

        if (projectStructureTree.getColumnModel().getColumnCount() > 0) {
            projectStructureTree.getColumnModel().getColumn(0).setMinWidth(90);
            projectStructureTree.getColumnModel().getColumn(0).setPreferredWidth(150);
            projectStructureTree.getColumnModel().getColumn(0).setMaxWidth(260);
            projectStructureTree.getColumnModel().getColumn(2).setMinWidth(40);
            projectStructureTree.getColumnModel().getColumn(2).setPreferredWidth(40);
            projectStructureTree.getColumnModel().getColumn(2).setMaxWidth(80);
            projectStructureTree.getColumnModel().getColumn(3).setMinWidth(40);
            projectStructureTree.getColumnModel().getColumn(3).setPreferredWidth(60);
            projectStructureTree.getColumnModel().getColumn(3).setMaxWidth(80);
            projectStructureTree.getColumnModel().getColumn(4).setMinWidth(20);
            projectStructureTree.getColumnModel().getColumn(4).setPreferredWidth(40);
            projectStructureTree.getColumnModel().getColumn(4).setMaxWidth(80);
            projectStructureTree.getColumnModel().getColumn(5).setMinWidth(20);
            projectStructureTree.getColumnModel().getColumn(5).setPreferredWidth(30);
            projectStructureTree.getColumnModel().getColumn(5).setMaxWidth(60);
            projectStructureTree.getColumnModel().getColumn(6).setMinWidth(20);
            projectStructureTree.getColumnModel().getColumn(6).setPreferredWidth(30);
            projectStructureTree.getColumnModel().getColumn(6).setMaxWidth(60);
            projectStructureTree.getColumnModel().getColumn(7).setMinWidth(0);
            projectStructureTree.getColumnModel().getColumn(7).setPreferredWidth(0);
            projectStructureTree.getColumnModel().getColumn(7).setMaxWidth(0);
            projectStructureTree.getColumnModel().getColumn(8).setMinWidth(0);
            projectStructureTree.getColumnModel().getColumn(8).setPreferredWidth(0);
            projectStructureTree.getColumnModel().getColumn(8).setMaxWidth(0);
        }
    }
    //endregion

    //region initSmetTree() - инициализация дерева смет, вызов из MainApp()
    private void initSmetTree() {
        try {
            Image iconLeaf = ImageIO.read(getClass().getResource("images/leaf.png"));
            smetStructureTree.setLeafIcon(new ImageIcon(iconLeaf));
            Image iconFolder = ImageIO.read(getClass().getResource("images/folder.png"));
            smetStructureTree.setOpenIcon(new ImageIcon(iconFolder));
            smetStructureTree.setClosedIcon(new ImageIcon(iconFolder));

        } catch (IOException e) {
            e.printStackTrace();
        }

        smetStructureTree.setSelectionBackground(new Color(255, 195, 128));
        smetStructureTree.setSelectionForeground(Color.black);
        smetStructureTree.setRowHeight(20);

        smetStructureTree.setGridColor( new Color (232, 220, 207) );
        smetStructureTree.setShowGrid(true, true);

//        Highlighter simpleStriping = HighlighterFactory.createAlternateStriping();
        PatternPredicate leafPr = new PatternPredicate(".", 3);
        ColorHighlighter leafs = new ColorHighlighter(leafPr, Color.white, null, new Color(255, 195, 128), Color.black);
        ColorHighlighter wbss = new ColorHighlighter(Color.lightGray, null, new Color(223, 164, 96), Color.white);
        Highlighter shading = new ShadingColorHighlighter(new HighlightPredicate.ColumnHighlightPredicate(7, 8));
        FontHighlighter fnt = new FontHighlighter(new HighlightPredicate.ColumnHighlightPredicate(8), new Font("Calibri", 1, 12));
        PatternPredicate rootPr = new PatternPredicate("Сметы", 1);
        ColorHighlighter rootHL = new ColorHighlighter(rootPr, Color.darkGray, Color.white, new Color(159, 99, 32), Color.white);
        PatternPredicate patternPred1 = new PatternPredicate("^Смета", 1);
        ColorHighlighter rootHL1 = new ColorHighlighter(patternPred1, Color.gray, Color.white, new Color(191, 131, 64), Color.white);
        PatternPredicate statusSmetReaady = new PatternPredicate("ready", 10);
        ColorHighlighter ssr = new ColorHighlighter(statusSmetReaady, new Color(188, 255, 188), Color.black, new Color(221, 195, 94), Color.black);
        PatternPredicate statusSmetInProgress = new PatternPredicate("inProgress", 10);
        ColorHighlighter ssip = new ColorHighlighter(statusSmetInProgress, new Color(255, 255, 198), Color.black, null, null);
        PatternPredicate linkWorkToSmet = new PatternPredicate("true", 9);
        ColorHighlighter lwts = new ColorHighlighter(linkWorkToSmet, new Color(229, 182, 255), Color.black, new Color(241, 159, 128), Color.black);
        smetStructureTree.setHighlighters(wbss, leafs, rootHL, rootHL1, shading, fnt, ssr, ssip, lwts);

        if (smetStructureTree.getColumnModel().getColumnCount() > 0) {
            smetStructureTree.getColumnModel().getColumn(0).setMinWidth(90);
            smetStructureTree.getColumnModel().getColumn(0).setPreferredWidth(120);
            smetStructureTree.getColumnModel().getColumn(0).setMaxWidth(160);
            smetStructureTree.getColumnModel().getColumn(2).setMinWidth(70);
            smetStructureTree.getColumnModel().getColumn(2).setPreferredWidth(90);
            smetStructureTree.getColumnModel().getColumn(2).setMaxWidth(120);
            smetStructureTree.getColumnModel().getColumn(3).setMinWidth(40);
            smetStructureTree.getColumnModel().getColumn(3).setPreferredWidth(60);
            smetStructureTree.getColumnModel().getColumn(3).setMaxWidth(80);
            smetStructureTree.getColumnModel().getColumn(4).setMinWidth(40);
            smetStructureTree.getColumnModel().getColumn(4).setPreferredWidth(60);
            smetStructureTree.getColumnModel().getColumn(4).setMaxWidth(80);
            smetStructureTree.getColumnModel().getColumn(5).setMinWidth(40);
            smetStructureTree.getColumnModel().getColumn(5).setPreferredWidth(60);
            smetStructureTree.getColumnModel().getColumn(5).setMaxWidth(80);
            smetStructureTree.getColumnModel().getColumn(6).setMinWidth(40);
            smetStructureTree.getColumnModel().getColumn(6).setPreferredWidth(60);
            smetStructureTree.getColumnModel().getColumn(6).setMaxWidth(80);
            smetStructureTree.getColumnModel().getColumn(7).setMinWidth(20);
            smetStructureTree.getColumnModel().getColumn(7).setPreferredWidth(50);
            smetStructureTree.getColumnModel().getColumn(7).setMaxWidth(70);
            smetStructureTree.getColumnModel().getColumn(8).setMinWidth(20);
            smetStructureTree.getColumnModel().getColumn(8).setPreferredWidth(50);
            smetStructureTree.getColumnModel().getColumn(8).setMaxWidth(70);
            smetStructureTree.getColumnModel().getColumn(9).setMinWidth(0);
            smetStructureTree.getColumnModel().getColumn(9).setPreferredWidth(0);
            smetStructureTree.getColumnModel().getColumn(9).setMaxWidth(0);
            smetStructureTree.getColumnModel().getColumn(10).setMinWidth(0);
            smetStructureTree.getColumnModel().getColumn(10).setPreferredWidth(0);
            smetStructureTree.getColumnModel().getColumn(10).setMaxWidth(0);
        }
        smetStructureTree.setBorder(BorderFactory.createMatteBorder(1, 0, 1, 1, SystemColor.activeCaptionBorder));
        smetStructureTree.addTreeSelectionListener(new TreeSelectionListener() {
            @Override
            public void valueChanged(TreeSelectionEvent treeSelectionEvent) {
                highlightTaskRows();
            }
        });
    }
    //endregion

    //region initComponents() - инициализация компонентов формы, вызов из MainApp()
    private void initComponents() {

        linkFrame = new javax.swing.JFrame();
        jScrollPane5 = new javax.swing.JScrollPane();
        linkTable = new javax.swing.JTable();
        jLabel6 = new javax.swing.JLabel();
        jSeparator6 = new javax.swing.JSeparator();

        openSmetDialog = new javax.swing.JDialog();
        jLabel4 = new javax.swing.JLabel();
        jSeparator7 = new javax.swing.JSeparator();
        jScrollPane6 = new javax.swing.JScrollPane();
        smetTree = new javax.swing.JTree();
        openSmetButton = new javax.swing.JButton();
        cancelOpenSmetButton = new javax.swing.JButton();
        addLinkDialog = new javax.swing.JDialog();
        jSeparator9 = new javax.swing.JSeparator();
        jScrollPane7 = new javax.swing.JScrollPane();
        addLinkTable = new javax.swing.JTable();
        jLabel5 = new javax.swing.JLabel();
        addLinkButton = new javax.swing.JButton();
        cancelAddLinkButton = new javax.swing.JButton();
        jPanel1 = new javax.swing.JPanel();
        statusBar = new StatusBar();
        primaveraToolBar = new javax.swing.JToolBar();
        jLabel1 = new javax.swing.JLabel();
        jSeparator1 = new javax.swing.JToolBar.Separator();
        loginPrimaveraButton = new javax.swing.JButton();
        synchButton = new javax.swing.JButton();
        validButton = new javax.swing.JButton();
        jSplitPane1 = new javax.swing.JSplitPane();
        jPanel2 = new javax.swing.JPanel();
        jScrollPane3 = new javax.swing.JScrollPane();
        projectStructureTree = new org.jdesktop.swingx.JXTreeTable();
        jToolBar2 = new javax.swing.JToolBar();
        jLabel2 = new javax.swing.JLabel();
        jSeparator2 = new javax.swing.JToolBar.Separator();
        openProjectDlgBtn = new javax.swing.JButton();
        showLinkFrameButton = new javax.swing.JButton();
        checkLinksButton = new javax.swing.JButton();
        jScrollPane1 = new javax.swing.JScrollPane();
        taskRsrcTable = new javax.swing.JTable();
        jPanel3 = new javax.swing.JPanel();
        jScrollPane4 = new javax.swing.JScrollPane();
        smetStructureTree = new org.jdesktop.swingx.JXTreeTable();
        jToolBar3 = new javax.swing.JToolBar();
        jLabel3 = new javax.swing.JLabel();
        jSeparator3 = new javax.swing.JToolBar.Separator();
        jSeparator3 = new javax.swing.JToolBar.Separator();
        openSmetDialogButton = new javax.swing.JButton();
        jScrollPane2 = new javax.swing.JScrollPane();



        panelFilterTask = new JPanel();

        //region Инициализация меню дерева работ
        menu_task_main = new JPopupMenu();

        addLink_task_main = new JMenuItem("Добавить связь");
        addLink_task_main.setPreferredSize(new Dimension(200, 25));
        addLink_task_main.setIcon(new ImageIcon(getClass().getResource("images/add.png")));
        addLink_task_main.addActionListener(new ActionListener() {
            @Override
            public void actionPerformed(ActionEvent evt) {
                addLink(evt);
            }
        });
        addLink_task_main.setEnabled(false);

        openProject_task_main = new JMenuItem("Открыть новый проект");
        openProject_task_main.setPreferredSize(new Dimension(200, 25));
        openProject_task_main.addActionListener(new ActionListener() {
            @Override
            public void actionPerformed(ActionEvent evt) {
                openSQLProject(evt);
            }
        });

        toggleFilter_task_main = new JMenuItem("Установить фильтр");
        toggleFilter_task_main.setIcon(new ImageIcon(getClass().getResource("images/filter.png")));
        toggleFilter_task_main.setToolTipText("");
        toggleFilter_task_main.setPreferredSize(new Dimension(200, 25));
        toggleFilter_task_main.setEnabled(false);
        toggleFilter_task_main.addActionListener(new ActionListener() {
            @Override
            public void actionPerformed(ActionEvent evt) {
                toggleTaskFilter(evt);
            }
        });

        addToFilter_task_main = new JMenuItem("Добавить к фильтру");
        addToFilter_task_main.setPreferredSize(new Dimension(200, 25));
        addToFilter_task_main.addActionListener(new ActionListener() {
            @Override
            public void actionPerformed(ActionEvent actionEvent) {
                addTaskToFilter();
            }
        });
        addToFilter_task_main.setEnabled(false);

        searchTask_task_main = new JMenuItem("Найти работу");
        searchTask_task_main.setPreferredSize(new Dimension(200, 25));
        searchTask_task_main.addActionListener(new ActionListener() {
            @Override
            public void actionPerformed(ActionEvent actionEvent) {
                foundTask();
            }
        });
        //searchTask_task_main.setEnabled(false);

        showLinkedSmet_task_main = new JMenuItem("Показать привязанные сметы");
        showLinkedSmet_task_main.addActionListener(new ActionListener() {
            @Override
            public void actionPerformed(ActionEvent actionEvent) {
                showMeLink();
            }
        });
        showLinkedSmet_task_main.setEnabled(false);

        removeLink_task_main = new JMenuItem("Удалить связь");
        removeLink_task_main.setPreferredSize(new Dimension(200, 25));
        removeLink_task_main.addActionListener(new ActionListener() {
            @Override
            public void actionPerformed(ActionEvent actionEvent) {
                removeLinkFromMenu();
            }
        });
        removeLink_task_main.setEnabled(false);

        menu_task_main.add(addLink_task_main);
        menu_task_main.add(removeLink_task_main);
        menu_task_main.add(new JPopupMenu.Separator());
        menu_task_main.add(openProject_task_main);
        menu_task_main.add(new JPopupMenu.Separator());
        menu_task_main.add(toggleFilter_task_main);
        menu_task_main.add(addToFilter_task_main);
        menu_task_main.add(new JPopupMenu.Separator());
        menu_task_main.add(searchTask_task_main);
        menu_task_main.add(showLinkedSmet_task_main);
        //endregion

        //region Инициализация меню дерева смет

        menu_smr_main = new javax.swing.JPopupMenu();

        addLink_smr_main = new javax.swing.JMenuItem("Добавить связь");
        try {
            Image iconAdd = ImageIO.read(getClass().getResource("images/add.png"));
            addLink_smr_main.setIcon( new ImageIcon(iconAdd) );
        } catch (IOException e) {e.printStackTrace();}
        addLink_smr_main.addActionListener(new ActionListener() {
            @Override
            public void actionPerformed(ActionEvent evt) {
                addLink(evt);
            }
        });
        addLink_smr_main.setEnabled(false);

        openSmet_smr_main = new javax.swing.JMenuItem("Открыть новую смету");
        openSmet_smr_main.addActionListener(new ActionListener() {
            @Override
            public void actionPerformed(ActionEvent evt) {
                openSmetDialog(evt);
            }
        });

        closeSmet_smr_main = new javax.swing.JMenuItem("Закрыть смету");
        closeSmet_smr_main.addActionListener(new ActionListener() {
            @Override
            public void actionPerformed(ActionEvent evt) {
                int[] selRows = smetStructureTree.getSelectedRows();

                for (int i = 0; i < smetStructureTree.getSelectedRowCount(); i++) {
                    SmetNode selNode = (SmetNode) smetStructureTree.getPathForRow(selRows[i]).getLastPathComponent();
                    if ( selNode.isHeader ) smetStructureTreeModel.closeSQLSmet( selNode );
                }

                smetStructureTree.updateUI();
            }
        });
        closeSmet_smr_main.setEnabled(false);

        removeLink_smr_main = new JMenuItem("Удалить связь");
        removeLink_smr_main.addActionListener(new ActionListener() {
            @Override
            public void actionPerformed(ActionEvent actionEvent) {
                removeLinkFromMenu();
            }
        });
        removeLink_smr_main.setEnabled(false);

        searchTaskFromSmet_smr_main = new JMenuItem("Найти связанные работы");
        searchTaskFromSmet_smr_main.setEnabled(false);
        searchTaskFromSmet_smr_main.addActionListener(new ActionListener() {
            @Override
            public void actionPerformed(ActionEvent actionEvent) {
                searchTask();
            }
        });

        menu_smr_main.add(addLink_smr_main);
        menu_smr_main.add(removeLink_smr_main);
        menu_smr_main.add(new JPopupMenu.Separator());
        menu_smr_main.add(openSmet_smr_main);
        menu_smr_main.add(closeSmet_smr_main);
        menu_smr_main.add(new JPopupMenu.Separator());
        menu_smr_main.add(searchTaskFromSmet_smr_main);

        //endregion

        //region Инициализация меню таблицы связей

        menu_linkFrame = new JPopupMenu();

        deleteLink = new JMenuItem("Удалить связь");
        deleteLink.addActionListener(new ActionListener() {
            @Override
            public void actionPerformed(ActionEvent evt) {
                removeLink(evt);
            }
        });

        menu_linkFrame.add(deleteLink);
        //endregion

        linkFrame.setTitle("Таблица связей");
        int width = 1050;
        int height = 700;
        Dimension screensize = Toolkit.getDefaultToolkit().getScreenSize();
        linkFrame.setLocation(screensize.width / 2 - width / 2, screensize.height / 2 - height / 2);

        linkBar = new JToolBar();
        linkBar.setFloatable(false);

        sortTaskButton = new JButton("Сортировка по работам");
        sortTaskButton.setFocusable(false);
        sortTaskButton.addActionListener(new ActionListener() {
            @Override
            public void actionPerformed(ActionEvent actionEvent) {
                sortLink("task");
            }
        });
        sortSmetButton = new JButton("Сортировка по сметам");
        sortSmetButton.setFocusable(false);
        sortSmetButton.addActionListener(new ActionListener() {
            @Override
            public void actionPerformed(ActionEvent actionEvent) {
                sortLink("smet");
            }
        });

        linkXMLButton = new JButton("Выгрузить в XML");
        linkXMLButton.setFocusable(false);
        linkXMLButton.addActionListener(new ActionListener() {
            @Override
            public void actionPerformed(ActionEvent actionEvent) {
                XMLTaskRscr xmlTask = new XMLTaskRscr();
                xmlTask.addConfig(linkTableArray.getLinkArray(), curProject.getName());
            }
        });

        linkBar.add(sortTaskButton);
        linkBar.add(sortSmetButton);
        linkBar.add(linkXMLButton);

        linkTable.addMouseListener(new MouseAdapter() {
            @Override
            public void mouseReleased(MouseEvent evt) {
                if (evt.isPopupTrigger()) {
                    menu_linkFrame.show( linkTable, evt.getX(), evt.getY() );
                    deleteLink.setEnabled(false);
                    if (linkTable.getSelectedRowCount() > 0) deleteLink.setEnabled(true);
                }
            }
        });

        jScrollPane5.setViewportView(linkTable);

        jLabel6.setFont(new java.awt.Font("Segoe UI Light", 0, 18)); // NOI18N
        jLabel6.setText("Текущие связи по проекту");

        jSeparator6.setBackground(java.awt.SystemColor.control);
        jSeparator6.setForeground(java.awt.SystemColor.activeCaptionBorder);

        filterTaskPanel = new FilterTaskPanel();
        panelFilterTask = filterTaskPanel.headPanel();
        filterTaskPanel.setFilterMenuItem(toggleFilter_task_main);

        javax.swing.GroupLayout linkFrameLayout = new javax.swing.GroupLayout(linkFrame.getContentPane());
        linkFrame.getContentPane().setLayout(linkFrameLayout);
        linkFrameLayout.setHorizontalGroup(
                linkFrameLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
                        .addComponent(jSeparator6)
                        .addGroup(linkFrameLayout.createSequentialGroup()
                                .addGroup(linkFrameLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
                                        .addGroup(linkFrameLayout.createSequentialGroup()
                                                .addGap(55, 55, 55)
                                                .addComponent(panelFilterTask))
                                        .addGroup(linkFrameLayout.createSequentialGroup()
                                                .addGap(55, 55, 55)
                                                .addComponent(linkBar))
                                        .addGroup(linkFrameLayout.createSequentialGroup()
                                                .addGap(56, 56, 56)
                                                .addComponent(jScrollPane5, javax.swing.GroupLayout.DEFAULT_SIZE, 888, Short.MAX_VALUE)))
                                .addGap(56, 56, 56))
        );
        linkFrameLayout.setVerticalGroup(
                linkFrameLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
                        .addGroup(javax.swing.GroupLayout.Alignment.TRAILING, linkFrameLayout.createSequentialGroup()
                                .addGap(6, 6, 6)
                                .addComponent(panelFilterTask)
                                .addGap(6, 6, 6)
                                .addComponent(jSeparator6, javax.swing.GroupLayout.PREFERRED_SIZE, 10, javax.swing.GroupLayout.PREFERRED_SIZE)
                                .addComponent(linkBar)
                                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED)
                                .addComponent(jScrollPane5, javax.swing.GroupLayout.DEFAULT_SIZE, 601, Short.MAX_VALUE)
                                .addGap(15, 15, 15))
        );

        openSmetDialog.setDefaultCloseOperation(javax.swing.WindowConstants.DISPOSE_ON_CLOSE);
        openSmetDialog.setAlwaysOnTop(true);
        openSmetDialog.setModalityType(java.awt.Dialog.ModalityType.TOOLKIT_MODAL);
        openSmetDialog.setType(java.awt.Window.Type.UTILITY);

        jLabel4.setFont(new java.awt.Font("Segoe UI Light", 0, 18)); // NOI18N
        jLabel4.setText("Выберите смету");

        jSeparator7.setBackground(java.awt.SystemColor.control);
        jSeparator7.setForeground(java.awt.SystemColor.activeCaptionBorder);

        javax.swing.tree.DefaultMutableTreeNode treeNode1 = new javax.swing.tree.DefaultMutableTreeNode("Сметы");
        smetTree.setModel(new javax.swing.tree.DefaultTreeModel(treeNode1));
        smetTree.setRowHeight(18);
        smetTree.setShowsRootHandles(true);
        smetTree.addMouseListener(new MouseAdapter() {
            public void mouseClicked(MouseEvent evt) {
                if (evt.getClickCount() == 2) {
                    SmetNode node = (SmetNode) smetTree.getLastSelectedPathComponent();

                    if ( node == null || !node.isString ) return;

                    smetStructureTreeModel.openSmet(node);
                    smetStructureTree.updateUI();
                    openSmetDialog.setVisible(false);

                    initLinkTable();
                    if (linkTableArray != null) {
                        smetStructureTreeModel.updateFact(linkTableArray.getLinkArray());
                        smetStructureTree.updateUI();
                    }
                }
            }
        });
        smetTree.addTreeSelectionListener(new javax.swing.event.TreeSelectionListener() {
            public void valueChanged(javax.swing.event.TreeSelectionEvent evt) {
                SmetNode node = (SmetNode) smetTree.getLastSelectedPathComponent();
                if (node == null)
                    return;
                openSmetButton.setEnabled( node.isString );
            }
        });
        jScrollPane6.setViewportView(smetTree);

        openSmetButton.setFont(new java.awt.Font("Calibri", 0, 12)); // NOI18N
        openSmetButton.setText("Open");
        openSmetButton.setEnabled(false);
        try {
            Image iconOpen = ImageIO.read(getClass().getResource("images/open.png"));
            openSmetButton.setIcon( new ImageIcon(iconOpen) );
            openSmetButton.setHorizontalAlignment(SwingConstants.RIGHT);
        } catch (IOException e) { e.printStackTrace(); }
        openSmetButton.setMargin(new java.awt.Insets(6, 14, 6, 14));
        openSmetButton.addActionListener(new ActionListener() {
            public void actionPerformed(ActionEvent evt) {
                open_smetDlg(evt);
            }
        });

        cancelOpenSmetButton.setFont(new java.awt.Font("Calibri", 0, 12)); // NOI18N
        cancelOpenSmetButton.setText("Cancel");
        try {
            Image iconCancel = ImageIO.read(getClass().getResource("images/cancel.png"));
            cancelOpenSmetButton.setIcon( new ImageIcon(iconCancel) );
            cancelOpenSmetButton.setHorizontalAlignment(SwingConstants.RIGHT);
        } catch (IOException e) { e.printStackTrace(); }
        cancelOpenSmetButton.setMargin(new java.awt.Insets(6, 14, 6, 14));
        cancelOpenSmetButton.addActionListener(new ActionListener() {
            public void actionPerformed(ActionEvent evt) {
                cancel_smetDlg(evt);
            }
        });

        javax.swing.GroupLayout openSmetDialogLayout = new javax.swing.GroupLayout(openSmetDialog.getContentPane());
        openSmetDialog.getContentPane().setLayout(openSmetDialogLayout);
        openSmetDialogLayout.setHorizontalGroup(
                openSmetDialogLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
                        .addGroup(javax.swing.GroupLayout.Alignment.TRAILING, openSmetDialogLayout.createSequentialGroup()
                                .addGap(0, 0, 0)
                                .addGroup(openSmetDialogLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
                                        .addGroup(openSmetDialogLayout.createSequentialGroup()
                                                .addGap(55, 55, 55)
                                                .addComponent(jLabel4))
                                        .addComponent(jSeparator7, javax.swing.GroupLayout.DEFAULT_SIZE, 600, Short.MAX_VALUE)
                                        .addGroup(openSmetDialogLayout.createSequentialGroup()
                                                .addGap(56, 56, 56)
                                                .addGroup(openSmetDialogLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.TRAILING)
                                                        .addGroup(openSmetDialogLayout.createSequentialGroup()
                                                                .addComponent(openSmetButton, javax.swing.GroupLayout.PREFERRED_SIZE, 102, javax.swing.GroupLayout.PREFERRED_SIZE)
                                                                .addGap(6, 6, 6)
                                                                .addComponent(cancelOpenSmetButton, javax.swing.GroupLayout.PREFERRED_SIZE, 102, javax.swing.GroupLayout.PREFERRED_SIZE))
                                                        .addComponent(jScrollPane6))
                                                .addGap(54, 54, 54))))
        );

        openSmetDialogLayout.setVerticalGroup(
                openSmetDialogLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
                        .addGroup(openSmetDialogLayout.createSequentialGroup()
                                .addGap(30, 30, 30)
                                .addComponent(jLabel4)
                                .addGap(6, 6, 6)
                                .addComponent(jSeparator7, javax.swing.GroupLayout.PREFERRED_SIZE, 10, javax.swing.GroupLayout.PREFERRED_SIZE)
                                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                                .addComponent(jScrollPane6, javax.swing.GroupLayout.DEFAULT_SIZE, 336, Short.MAX_VALUE)
                                .addGap(18, 18, 18)
                                .addGroup(openSmetDialogLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
                                        .addComponent(openSmetButton, javax.swing.GroupLayout.PREFERRED_SIZE, 27, javax.swing.GroupLayout.PREFERRED_SIZE)
                                        .addComponent(cancelOpenSmetButton, javax.swing.GroupLayout.PREFERRED_SIZE, 27, javax.swing.GroupLayout.PREFERRED_SIZE))
                                .addGap(56, 56, 56))
        );

        setDefaultCloseOperation(javax.swing.WindowConstants.EXIT_ON_CLOSE);
        setTitle("Factage");

        primaveraToolBar.setRollover(true);
        primaveraToolBar.setFloatable(false);

        jLabel1.setFont(new java.awt.Font("Calibri", Font.BOLD, 14)); // NOI18N
        jLabel1.setForeground(new Color(102, 102, 102));
        jLabel1.setText("PRIMAVERA");
        jLabel1.setBorder(BorderFactory.createEmptyBorder(5, 12, 1, 10));
        primaveraToolBar.add(jLabel1);
        primaveraToolBar.add(jSeparator1);

        loginPrimaveraButton.setText("Вход");
        try {
            Image iconLogin = ImageIO.read(getClass().getResource("images/login.png"));
            loginPrimaveraButton.setIcon(new ImageIcon(iconLogin));
            loginPrimaveraButton.setHorizontalAlignment(SwingConstants.RIGHT);
        } catch (IOException e) { e.printStackTrace(); }
        loginPrimaveraButton.setFocusable(false);
        loginPrimaveraButton.addActionListener(new ActionListener() {
            public void actionPerformed(ActionEvent evt) {
                loginPrimavera(evt);
            }
        });
        primaveraToolBar.add(loginPrimaveraButton);

        synchButton.setText("Синхронизация");
        synchButton.setFocusable(false);
        try {
            Image iconSynch = ImageIO.read(getClass().getResource("images/synch.png"));
            synchButton.setIcon( new ImageIcon(iconSynch) );
            synchButton.setHorizontalAlignment(SwingConstants.RIGHT);
        } catch (IOException e) { e.printStackTrace(); }
        synchButton.addActionListener(new ActionListener() {
            public void actionPerformed(ActionEvent evt) {
                synchProject(evt);
            }
        });
        synchButton.setEnabled(false);
        primaveraToolBar.add(synchButton);

        validButton.setText("Валидация");
        validButton.setFocusable(false);
        try {
            Image iconValid = ImageIO.read(getClass().getResource("images/valid.png"));
            validButton.setIcon( new ImageIcon(iconValid) );
            validButton.setHorizontalAlignment(SwingConstants.RIGHT);
        } catch (IOException e) { e.printStackTrace(); }
        validButton.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                validProject(evt);
            }
        });
        validButton.setEnabled(false);
        primaveraToolBar.add(validButton);
        primaveraToolBar.add(new JToolBar.Separator());
        primaveraToolBar.add(new JLabel("v.0.9.9.10"));
        //region ТХМ редакция
//        primaveraToolBar.add(new JLabel("v.0.9.4.ТХМ"));
        //endregion

        jScrollPane3.setBorder(BorderFactory.createMatteBorder(1, 0, 1, 0, SystemColor.activeCaptionBorder));
        jScrollPane3.setViewportView(projectStructureTree);
        projectStructureTree.addMouseListener(new MouseAdapter() {
            @Override
            public void mouseReleased(MouseEvent evt) {
                showProjectMenu(evt);
            }
        });

        jToolBar2.setRollover(true);
        jToolBar2.setBackground(new Color(130, 130, 130));

        jLabel2.setFont(new java.awt.Font("Calibri", 0, 12)); // NOI18N
        jLabel2.setForeground(new java.awt.Color(200, 200, 200));
        jLabel2.setText("СТРУКТУРА ПРОЕКТА");
        jLabel2.setBorder(javax.swing.BorderFactory.createEmptyBorder(4, 10, 1, 10));
        jToolBar2.add(jLabel2);
        jToolBar2.add(jSeparator2);

        openProjectDlgBtn.setText("Открыть проект");
        openProjectDlgBtn.setFocusable(false);
        openProjectDlgBtn.setMargin(new Insets(4, 5, 4, 5));
        openProjectDlgBtn.setBackground(new Color(130, 130, 130));
        openProjectDlgBtn.setForeground(new Color(240, 240, 240));


        openProjectDlgBtn.setIcon(new ImageIcon(getClass().getResource("images/open.png")));
        openProjectDlgBtn.setHorizontalAlignment(SwingConstants.RIGHT);
        openProjectDlgBtn.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                openSQLProject(evt);
            }
        });
        jToolBar2.add(openProjectDlgBtn);
        jToolBar2.setFloatable(false);
        jToolBar3.setFloatable(false);

        showLinkFrameButton.setText("Таблица связей");
        showLinkFrameButton.setFocusable(false);
        showLinkFrameButton.setMargin(new Insets(4, 5, 4, 5));
        showLinkFrameButton.setBackground(new Color(130, 130, 130));
        showLinkFrameButton.setForeground(new Color(240, 240, 240));

        lockProjectButton = new javax.swing.JButton();
        lockProjectButton.setText("Lock/Unlock project");
        lockProjectButton.setFocusable(false);
        lockProjectButton.setMargin(new Insets(4, 5, 4, 5));
        lockProjectButton.setBackground(new Color(130, 130, 130));
        lockProjectButton.setForeground(new Color(240, 240, 240));
        lockProjectButton.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                //showLinkFrameButtonActionPerformed(evt);
//            try {
//                if (curProject != null && loginFunc.session.isValid() ) {
//
//                    PrimaveraProject testPrimaProject = new PrimaveraProject(loginFunc.session, curProject);
//                    Project testProject = testPrimaProject.getCurProject();
//
//                    System.out.println ("Check out user id = " + testProject.getCheckOutUserObjectId().toString());
//
//                        if ( testProject.isProjectLocked(true) ) {
//                                if (testProject.unlockProject()) {
//                                    System.out.println ("project unlocked!");
//                                } else {
//                                    System.out.println ("project not unlocked!");
//                                }
//                        } else {
//                            if (testProject.lockProject()) {
//                                System.out.println ("project locked!");
//                            } else {
//                                System.out.println ("project not locked!");
//                            }
//                        }
//                }
//            } catch (BusinessObjectException | ServerException | NetworkException e) {
//                e.printStackTrace();
//            }
            }
        });
        //jToolBar2.add(lockProjectButton);

        showLinkFrameButton.setIcon(new ImageIcon(getClass().getResource("images/table.png")));
        showLinkFrameButton.setHorizontalAlignment(SwingConstants.RIGHT);
        showLinkFrameButton.addActionListener(new ActionListener() {
            @Override
            public void actionPerformed(ActionEvent evt) {
                linkFrame.setVisible(true);
            }
        });
        jToolBar2.add(showLinkFrameButton);

        updateRaButton = new JButton("Пересчет назначений");
        updateRaButton.setEnabled(false);
        updateRaButton.setFocusable(false);
        updateRaButton.setMargin(new Insets(4, 5, 4, 5));
        updateRaButton.setBackground(new Color(130, 130, 130));
        updateRaButton.setForeground(new Color(240, 240, 240));
        updateRaButton.addActionListener(new ActionListener() {
            public void actionPerformed(ActionEvent evt) {
                if (curProject == null) return;
                UpdateProjectRaThread updateRa = new UpdateProjectRaThread(curProject, linkTableArray, rsrcMap);
                updateRa.start();

            }
        });
        //jToolBar2.add(updateRaButton);
//        loadExcelLinks = new JButton("Excel Links");
//        loadExcelLinks.setFocusable(false);
//        loadExcelLinks.addActionListener(new ActionListener() {
//            @Override
//            public void actionPerformed(ActionEvent actionEvent) {
//                JFileChooser jFileChooser = new JFileChooser();
//                int ret = jFileChooser.showDialog(null, "Открыть файл");
//                File file = null;
//                if (ret == JFileChooser.APPROVE_OPTION) {
//                    file = jFileChooser.getSelectedFile();
//                }
//
//                parseLinkFile(file);
//            }
//        });
//        jToolBar2.add(loadExcelLinks);

        checkLinksButton.setText("Проверить связи");
        checkLinksButton.setFocusable(false);
        checkLinksButton.addActionListener(new ActionListener() {
            @Override
            public void actionPerformed(ActionEvent evt) {
                checkLinkshours();
            }
        });
//        jToolBar2.add(checkLinksButton);


        taskRsrcTable.setModel(new javax.swing.table.DefaultTableModel(
                new Object[][]{
                        {null, "Нет ресурсов для отображения", null, null}
                },
                new String[]{"ID", "Наименование ресурса", "Кол-во", "Тип ресурса"}
        ));
        jScrollPane1.setViewportView(taskRsrcTable);
        jScrollPane1.setBorder(BorderFactory.createMatteBorder(1, 1, 1, 0, SystemColor.activeCaptionBorder));

        javax.swing.GroupLayout jPanel2Layout = new javax.swing.GroupLayout(jPanel2);
        jPanel2.setLayout(jPanel2Layout);
        jPanel2Layout.setHorizontalGroup(
                jPanel2Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
                        .addComponent(jScrollPane3)
                        .addComponent(jToolBar2, javax.swing.GroupLayout.DEFAULT_SIZE, 499, Short.MAX_VALUE)
                        .addComponent(jScrollPane1)
        );
        jPanel2Layout.setVerticalGroup(
                jPanel2Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
                        .addGroup(jPanel2Layout.createSequentialGroup()
                                .addComponent(jToolBar2, javax.swing.GroupLayout.PREFERRED_SIZE, 25, javax.swing.GroupLayout.PREFERRED_SIZE)
                                        //.addGap(13, 13, 13)
                                .addComponent(jScrollPane3, javax.swing.GroupLayout.DEFAULT_SIZE, 430, Short.MAX_VALUE)
                                .addGap(36, 36, 36)
                                .addComponent(jScrollPane1, javax.swing.GroupLayout.PREFERRED_SIZE, 155, javax.swing.GroupLayout.PREFERRED_SIZE))
        );

        jSplitPane1.setLeftComponent(jPanel2);

        jScrollPane4.setViewportView(smetStructureTree);
        jScrollPane4.setBorder(BorderFactory.createMatteBorder(1, 0, 0, 0, SystemColor.activeCaptionBorder));
        smetStructureTree.addMouseListener(new MouseAdapter() {
            @Override
            public void mouseReleased(MouseEvent evt) {
                showSmetMenu(evt);
            }
            @Override
            public void mouseClicked(MouseEvent mouseEvent) {
                Point p = mouseEvent.getPoint();
                if (mouseEvent.getClickCount() == 2) {
//                    int row = smetStructureTree.getSelectedRow();
//                    SmetNode node = (SmetNode) smetStructureTreeModel.getSmRow(row, smetStructureTreeModel.getRoot());
//                    System.out.println(node.getName());
                    int row = smetStructureTree.rowAtPoint(p);
                    SmetNode smetNodeRow = (SmetNode) smetStructureTree.getPathForRow(row).getLastPathComponent();
                    int childCount = smetStructureTreeModel.getChildCount(smetNodeRow);
                    boolean isNextChild = false;
                    int treeRowCount = smetStructureTree.getRowCount()-1;
//                    System.out.println("row: " + row + "        | rowCount: " + treeRowCount);
                    if (row != 0) {
                        if (row != treeRowCount) {
                            SmetNode smetNodeRowChild = (SmetNode) smetStructureTree.getPathForRow(row+1).getLastPathComponent();
                            if (smetNodeRowChild.getParentId() == smetNodeRow.getId()) {
                                isNextChild = true;
                            }
                            if (!isNextChild) {
                                if (childCount != 0) {
                                    expandNode(smetStructureTree, row, childCount);
                                }
                            } else {
                                if (childCount != 0) {
                                    collapseNode(smetStructureTree, row, childCount);
                                }
                            }
                        } else {
                            if (!isNextChild) {
                                if (childCount != 0) {
                                    expandNode(smetStructureTree, row, childCount);
                                }
                            } else {
                                if (childCount != 0) {
                                    collapseNode(smetStructureTree, row, childCount);
                                }
                            }
                        }

                    } else {
                        if (smetStructureTree.getPathForRow(row+1) != null) {
                            collapseTree(smetStructureTree);
                        } else {
                            expandTree(smetStructureTree);
                        }
                    }
                }
            }
        });

        jToolBar3.setRollover(true);

        jLabel3.setFont(new java.awt.Font("Calibri", 0, 12)); // NOI18N
        jLabel3.setForeground(new java.awt.Color(200, 200, 200));
        jLabel3.setText("СМЕТЫ");
        jLabel3.setBorder(javax.swing.BorderFactory.createEmptyBorder(4, 10, 1, 10));
        jToolBar3.add(jLabel3);
        jToolBar3.add(jSeparator3);
        jToolBar2.setFloatable(false);

        openSmetDialogButton.setText("Открыть смету");
        openSmetDialogButton.setBackground(new Color(130, 130, 130));
        openSmetDialogButton.setForeground(new Color(240, 240, 240));
        openSmetDialogButton.setMargin(new Insets(4, 5, 4, 5));
        openSmetDialogButton.setFocusable(false);
        try {
            Image iconOpen = ImageIO.read(getClass().getResource("images/open.png"));
            openSmetDialogButton.setIcon( new ImageIcon(iconOpen) );
            openSmetDialogButton.setHorizontalAlignment(SwingConstants.RIGHT);
        } catch (IOException e) { e.printStackTrace(); }
        openSmetDialogButton.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(ActionEvent evt) {
                openSmetDialog(evt);
            }
        });
        jToolBar3.add(openSmetDialogButton);
        jToolBar3.setBackground(new Color(130, 130, 130));

        javax.swing.GroupLayout jPanel3Layout = new javax.swing.GroupLayout(jPanel3);
        jPanel3.setLayout(jPanel3Layout);
        jPanel3Layout.setHorizontalGroup(
                jPanel3Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
                        .addComponent(jScrollPane4, javax.swing.GroupLayout.DEFAULT_SIZE, 701, Short.MAX_VALUE)
                        .addComponent(jToolBar3, javax.swing.GroupLayout.DEFAULT_SIZE, 701, Short.MAX_VALUE)
        );
        jPanel3Layout.setVerticalGroup(
                jPanel3Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
                        .addGroup(jPanel3Layout.createSequentialGroup()
                                .addComponent(jToolBar3, javax.swing.GroupLayout.PREFERRED_SIZE, 25, javax.swing.GroupLayout.PREFERRED_SIZE)
                                        //.addGap(13, 13, 13)
                                .addComponent(jScrollPane4, javax.swing.GroupLayout.DEFAULT_SIZE, 430, Short.MAX_VALUE))
        );

        jSplitPane1.setRightComponent(jPanel3);

        javax.swing.GroupLayout jPanel1Layout = new javax.swing.GroupLayout(jPanel1);
        jPanel1.setLayout(jPanel1Layout);
        jPanel1Layout.setHorizontalGroup(
                jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
                        .addComponent(primaveraToolBar, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
                        .addComponent(jSplitPane1)
                        .addComponent(statusBar, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
        );
        jPanel1Layout.setVerticalGroup(
                jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
                        .addGroup(jPanel1Layout.createSequentialGroup()
                                .addComponent(primaveraToolBar, javax.swing.GroupLayout.PREFERRED_SIZE, 25, javax.swing.GroupLayout.PREFERRED_SIZE)
                                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                                .addComponent(jSplitPane1)
                                .addComponent(statusBar, javax.swing.GroupLayout.PREFERRED_SIZE, 25, javax.swing.GroupLayout.PREFERRED_SIZE))
        );

        javax.swing.GroupLayout layout = new javax.swing.GroupLayout(getContentPane());
        getContentPane().setLayout(layout);
        layout.setHorizontalGroup(
                layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
                        .addComponent(jPanel1, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
        );
        layout.setVerticalGroup(
                layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
                        .addComponent(jPanel1, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
        );

        JLabel userLabel = new JLabel(FactageApp.user != null ? "Пользователь: " + FactageApp.user.getName() + "  |  Роль: " + FactageApp.user.getRoleName() : "");
        userLabel.setForeground(Color.white);
        statusBar.add(userLabel, new GridBagConstraints(0, 0, 1, 1, 0.1, 0.1, GridBagConstraints.WEST, GridBagConstraints.WEST, new Insets(3, 20, 0, 0), 0, 0));

        jMenuBar1 = new javax.swing.JMenuBar();

        jMenu1 = new javax.swing.JMenu("Проект");
        jMenu1.setMargin(new java.awt.Insets(0, 10, 0, 0));

        jMenuItem7 = new javax.swing.JMenuItem("Открыть проект");
        jMenuItem7.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                openSQLProject(evt);
            }
        });

        jMenuItem8 = new javax.swing.JMenuItem("Таблица связей");
        jMenuItem8.setEnabled(false);
        jMenuItem8.addActionListener(new ActionListener() {
            public void actionPerformed(ActionEvent evt) {
                linkFrame.setVisible(true);
            }
        });

        jMenuItem13 = new javax.swing.JMenuItem("Пересчет назначений");
        jMenuItem13.setEnabled(false);
        jMenuItem13.addActionListener(new ActionListener() {
            public void actionPerformed(ActionEvent evt) {
                if (curProject == null) return;

                Object[] options = {"Да", "Нет"};

                int choice = JOptionPane.showOptionDialog(FactageApp.ma,
                    "Вы уверены, что хотите запустить пересчет назначений по проекту?\n",
                    "Пересчет назначений",
                    JOptionPane.YES_NO_OPTION,
                    JOptionPane.QUESTION_MESSAGE,
                    null,
                    options,
                    options[0]);

                if (choice == 1) return;

                UpdateProjectRaThread updateRa = new UpdateProjectRaThread(curProject, linkTableArray, rsrcMap);
                updateRa.start();
            }
        });

        jMenu1.add(jMenuItem7);
        jMenu1.add(jMenuItem8);
        jMenu1.add(new JPopupMenu.Separator());
        jMenu1.add(jMenuItem13);
        jMenuBar1.add(jMenu1);

        jMenu2 = new javax.swing.JMenu("Сметы");

        jMenuItem9 = new javax.swing.JMenuItem("Открыть смету");
        jMenuItem9.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                open_smetDlg(evt);
            }
        });

        jMenu2.add(jMenuItem9);
        jMenuBar1.add(jMenu2);




        jMenu5 = new javax.swing.JMenu("Отчеты");

        jMenuItem10 = new javax.swing.JMenuItem("Привязка расценок к работам графика");
        jMenuItem10.setEnabled(false);
        jMenuItem10.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                KSForm ksForm = new KSForm(curProject, linkTableArray);
                ksForm.openKSForm();
            }
        });
        jMenu5.add(jMenuItem10);

        jMenuItem11 = new javax.swing.JMenuItem("Привязка работ графика к сметам");
        jMenuItem11.setEnabled(false);
        jMenuItem11.addActionListener(new ActionListener() {
            public void actionPerformed(ActionEvent evt) {
                SKForm skForm = new SKForm(curProject, linkTableArray);
                skForm.chooseSmet();
            }
        });

        jMenu5.add(jMenuItem11);
        jMenu5.add(new JPopupMenu.Separator());

        JMenuItem jMenuItemProgress = new JMenuItem("Прогресс смет");
        jMenuItemProgress.addActionListener(new ActionListener() {
            @Override
            public void actionPerformed(ActionEvent actionEvent) {
                XLSLinkSmet xlsLinkSmet = new XLSLinkSmet();
                xlsLinkSmet.start();
            }
        });

        jMenu5.add(jMenuItemProgress);

        jMenuItem12 = new javax.swing.JMenuItem("Выгрузка сводных таблиц (3 типа)");
        jMenuItem12.addActionListener(new ActionListener() {
            public void actionPerformed(ActionEvent evt) {
                openSumDataTableDlg("normal");

            }
        });

        jMenuItemExtendedReport = new JMenuItem("Выгрузка расширенного отчета по сводной таблице 1-го типа");
        jMenuItemExtendedReport.addActionListener(new ActionListener() {
            public void actionPerformed(ActionEvent evt) {
                openSumDataTableDlg("extend");

            }
        });

        jMenuItemMatrixReportSmet = new JMenuItem("<html>Выгрузка расширенного отчёта по сводной таблице 1-го типа<p> с группировкой по сметам</p></html>");
        jMenuItemMatrixReportSmet.addActionListener(new ActionListener() {
            @Override
            public void actionPerformed(ActionEvent actionEvent) {
                openSumDataTableDlg("extendSmet");
            }
        });

        jMenuItemMatrixReportTask = new JMenuItem("Выгрузка сводных таблиц (3 типа) с детализацией по работам");
        jMenuItemMatrixReportTask.addActionListener(new ActionListener() {
            @Override
            public void actionPerformed(ActionEvent actionEvent) {
                openSumDataTableDlg("normalTask");
            }
        });

        jMenu5.add(jMenuItem12);
        jMenu5.add(jMenuItemMatrixReportTask);
        jMenu5.add(jMenuItemExtendedReport);
        jMenu5.add(jMenuItemMatrixReportSmet);
        jMenu5.add(new JPopupMenu.Separator());

        JMenuItem jMenuItemSmetReport = new JMenuItem("Отчет по привязке смет - КИНЕФ");
        jMenuItemSmetReport.addActionListener(new ActionListener() {
            public void actionPerformed(ActionEvent evt) {
                CheckSmetReport report = new CheckSmetReport();
                report.run();
            }
        });
        jMenu5.add(jMenuItemSmetReport);

        jMenuBar1.add(jMenu5);

        jMenuConfig = new JMenu("Настройки");

        jMenuItemConfig = new JMenuItem("Конфигурация");
        jMenuItemConfig.addActionListener(new ActionListener() {
            @Override
            public void actionPerformed(ActionEvent actionEvent) {
                projectConfig.editConfig();
            }
        });
        jMenuConfig.add(jMenuItemConfig);

        jMenuBar1.add(jMenuConfig);

        JMenu adminMenu = new javax.swing.JMenu("Администрирование");
        JMenuItem usersMenuItem = new javax.swing.JMenuItem("Управление пользователями");
        usersMenuItem.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                new UsersDialog();
            }
       });

        adminMenu.add(usersMenuItem);
        if (FactageApp.user != null && FactageApp.user.getRoleId() == 4) jMenuBar1.add(adminMenu);

        setJMenuBar(jMenuBar1);
        pack();

        jSplitPane1.setDividerLocation(0.5);
        jSplitPane1.setResizeWeight(0.5);
        jSplitPane1.setDividerSize(2);
        jSplitPane1.setBorder(BorderFactory.createMatteBorder(1, 1, 1, 1, SystemColor.activeCaptionBorder));
        jSplitPane1.setForeground(SystemColor.activeCaptionBorder);
        ((BasicSplitPaneUI)jSplitPane1.getUI()).getDivider().setBorder(BorderFactory.createMatteBorder(1, 1, 1, 1, new Color(150, 150, 150)));
    }
    //endregion

    //region centerOnScreen(Container win) - Расположение окна по центру экрана
    private void centerOnScreen(Container win) {
        GraphicsDevice gd = GraphicsEnvironment.getLocalGraphicsEnvironment().getDefaultScreenDevice();
        Rectangle bounds = gd.getDefaultConfiguration().getBounds();
        Dimension winDim = win.getSize();
        Point loc = new Point((bounds.width - winDim.width) / 2, (bounds.height - winDim.height) / 2);
        win.setLocation(loc);
    }
    //endregion

    //endregion Блок. Методы инициализации

    //region Блок. Методы работы с Primavera: loginPrimavera, synchProject, validProject, checkUserAccess

    //region loginPrimavera(ActionEvent evt) - Подключение к Primavera
    private void loginPrimavera(ActionEvent evt) {
        //Засерить кнопки
        synchButton.setEnabled(false);
        validButton.setEnabled(false);

        loginFunc = new LoginFunctions();
        new LoginDialog(loginFunc);

        try {
            if (loginFunc.session != null && loginFunc.session.isValid()) {
                synchButton.setEnabled(true);
                validButton.setEnabled(true);
            }

        } catch (NetworkException e) {
            e.printStackTrace();
        }
    }
    //endregion

    //region synchProject(ActionEvent evt) - Синхронизация проекта
    private void synchProject(ActionEvent evt) {
        op = new OpenProjectDialog(this, true, loginFunc.session);
        op.setVisible(true);

        if (op.curProject != null) {
            curProject = op.curProject;
            PrimaveraProject primaProject = new PrimaveraProject(loginFunc.session, curProject);
            SynchThread synch = new SynchThread(primaProject);
            synch.start();
        }
    }
    //endregion

    //region validProject(ActionEvent evt) - Валидация проекта
    private void validProject(ActionEvent evt) {

        ValidThread valid = new ValidThread(curProject, loginFunc);
        if (curProject == null) {
            JOptionPane.showMessageDialog(this, "Проект для валидации не открыт.\nОткройте проект для валидации.", "Ошибка", JOptionPane.ERROR_MESSAGE);
            return;
        }

        if (checkUserAccess()) {
            valid.start();
        }
    }
    //endregion

    //region checkUserAccess() - проверка пользователя Primavera на наличие флага "Все ресурсы", вызов из ValidProject()
    private boolean checkUserAccess() {
        try {
            String whereClause = "ObjectId = " + loginFunc.session.getUserObjectId();
            BOIterator<User> users = loginFunc.session.getGlobalObjectManager().loadUsers(
                    new String[] {"ObjectId", "Name", "AllResourceAccessFlag", "GlobalProfileObjectId", "PersonalName"}, whereClause, null);

            User curUser = null;
            while (users.hasNext()) curUser = users.next();

            if (!curUser.getAllResourceAccessFlag())
                JOptionPane.showMessageDialog(this, "Пользователь: " + curUser.getPersonalName() + " не имеет прав для работы со всеми ресурсами.\nФункция валидации будет недоступна.\nОбратитесь к администратора Primavera для устранения.", "Ошибка", JOptionPane.ERROR_MESSAGE);

            return curUser.getAllResourceAccessFlag();
        } catch (ServerException | NetworkException | BusinessObjectException e) {
            e.printStackTrace();
        }
        return false;
    }
    //endregion

    //endregion Блок. Методы работы с Primavera: loginPrimavera, synchProject, validProject, checkUserAccess

    //region Блок. Методы подсветки работ и смет

    //region isTaskUse(ProjectNode node) - подсветка зеленым работ, имеющих привязку
    private void isTaskUse(ProjectNode node) {
        if (node.isTask()) {
            node.setTaskUse("");
            for (SQLLink link : linkTableArray.getLinkArray()) {
                if (node.getId() == link.getTaskId()) {
                    node.setTaskUse("true");
                    break;
                }
            }
        } else {
            if (node.getChildren() != null && node.getChildCount() > 0) {
                for (ProjectNode child : node.getChildren()) {
                    isTaskUse(child);
                }
            }
        }

    }
    //endregion

    //region highlightSmRows() - Индикация строк смет связанных с выделенной работой
    private void highlightSmRows() {
        //region Отключение пунктов меню
        removeLink_smr_main.setEnabled(false);
        addLink_smr_main.setEnabled(false);
        removeLink_task_main.setEnabled(false);
        addLink_task_main.setEnabled(false);
        showLinkedSmet_task_main.setEnabled(false);
        toggleFilter_task_main.setEnabled(false);
        //endregion

        //region Снятие подсветки со всех сметных строк
        if (smetStructureTreeModel.getRoot().getChildCount() != 0)
            smetStructureTreeModel.nullHigh(smetStructureTreeModel.getRoot());
        //endregion

        int[] selRows = projectStructureTree.getSelectedRows();

        String linkAction = "";

        for (int selRow : selRows) {
            ProjectNode selTask = (ProjectNode) projectStructureTree.getPathForRow(selRow).getLastPathComponent();
            //region Отображение ресурсов для выбранной работы
            updateRsrcTable(selTask.getRsrc());
            //endregion

            if (!selTask.isTask()) continue;

            for (SQLLink link : linkTableArray.getLinkArray()) {
                if (link.getTaskId() != selTask.getId()) continue;
                showLinkedSmet_task_main.setEnabled(true);

                //region Проверка включения пунктов меню "Фильтр"
                if (linkTableArray.getFilter()) {
                    addToFilter_task_main.setVisible(false);
                    if (filterTaskPanel.isNewTask(getSelectedTask())) {
                        addToFilter_task_main.setVisible(true);
                        addToFilter_task_main.setEnabled(true);
                        menu_task_main.pack();
                    }
                    toggleFilter_task_main.setText("Убрать фильтр");
                    toggleFilter_task_main.setEnabled(true);
                } else {
                    toggleFilter_task_main.setText("Установить фильтр");
                    toggleFilter_task_main.setEnabled(true);
                    addToFilter_task_main.setVisible(false);
                    menu_task_main.pack();
                }
                //endregion

                //region Подсветка связанных сметных строк
                if (smetStructureTreeModel.getSmRow(link.getSmrId(), smetStructureTreeModel.getRoot()) != null) {
                    smetStructureTreeModel.getSmRow(link.getSmrId(), smetStructureTreeModel.getRoot()).setHigh("true");
                }
                //endregion

                int[] selSmRows = smetStructureTree.getSelectedRows();

                for (int selSmRow : selSmRows) {
                    SmetNode selSmr = (SmetNode) smetStructureTree.getPathForRow(selSmRow).getLastPathComponent();

                    if (!selSmr.isString) continue;

                    addLink_smr_main.setEnabled(true);
                    addLink_task_main.setEnabled(true);
                    linkAction = (linkAction == "" ? "Добавить связь" : "Добавить/Изменить связь");

                    if (link.getSmrId() == selSmr.getId()) {
                        linkAction = (linkAction == "" ? "Изменить связь" : "Добавить/Изменить связь");
                        removeLink_task_main.setEnabled(true);
                        removeLink_smr_main.setEnabled(true);
                    }
                }
            }
        }
        int[] selSmRows = smetStructureTree.getSelectedRows();

        for (int i = 0; i < selSmRows.length; i++) {
            SmetNode selSmr = (SmetNode) smetStructureTree.getPathForRow(selSmRows[i]).getLastPathComponent();

            if (!selSmr.isString) continue;

            addLink_smr_main.setEnabled(true);
            addLink_task_main.setEnabled(true);
            linkAction = (linkAction == ""?"Добавить связь" : "Добавить/Изменить связь");
        }

        addLink_smr_main.setText(linkAction == "" ? "Добавить связь" : linkAction);
        addLink_task_main.setText(linkAction == "" ? "Добавить связь" : linkAction);
        smetStructureTree.repaint();
    }
    //endregion

    //region highlightTaskRows() - индикация строк работ связанных с выделенной сметой
    private void highlightTaskRows() {
        //region Отключаем пункты меню
        removeLink_task_main.setEnabled(false);
        addLink_task_main.setEnabled(false);
        removeLink_smr_main.setEnabled(false);
        addLink_smr_main.setEnabled(false);
        closeSmet_smr_main.setEnabled(false);
        searchTaskFromSmet_smr_main.setEnabled(false);
        //endregion

        if (smetStructureTree.getSelectedRowCount() == 0) return;

        int[] selSmRows = smetStructureTree.getSelectedRows();

        for (int selSmRow : selSmRows) {
            SmetNode selSmr = (SmetNode) smetStructureTree.getPathForRow(selSmRow).getLastPathComponent();
            if (selSmr.isHeader) {
                closeSmet_smr_main.setEnabled(true);
                continue;
            }
        }
        if (curProject == null) return;

        projectStructureModel.nullHigh(curProject);

        String linkAction = "";

        for (int selSmRow : selSmRows) {

            SmetNode selSmr = (SmetNode) smetStructureTree.getPathForRow(selSmRow).getLastPathComponent();

            if (!selSmr.isString) continue;

            for (SQLLink link : linkTableArray.getLinkArray()) {
                if (link.getSmrId() != selSmr.getId()) continue;
                searchTaskFromSmet_smr_main.setEnabled(true);

                taskMap.get(link.getTaskId()).setHigh("true");
                //if (projectStructureModel.getTask(link.getTaskId(), curProject) != null) projectStructureModel.getTask(link.getTaskId(), curProject).setHigh("true");

                int[] selRows = projectStructureTree.getSelectedRows();
                for (int selRow : selRows) {
                    ProjectNode selTask = (ProjectNode) projectStructureTree.getPathForRow(selRow).getLastPathComponent();

                    if (!selTask.isTask()) continue;

                    addLink_smr_main.setEnabled(true);

                    linkAction = (linkAction.equals("") ? "Добавить связь" : "Добавить/Изменить связь");
                    if (link.getTaskId() == selTask.getId()) {
                        removeLink_smr_main.setEnabled(true);
                        linkAction = (linkAction.equals("") ? "Изменить связь" : "Добавить/Изменить связь");
                    }

                }
            }
        }

        for (int selRow : projectStructureTree.getSelectedRows()) {
            ProjectNode selTask = (ProjectNode) projectStructureTree.getPathForRow(selRow).getLastPathComponent();

            if (!selTask.isTask()) continue;

            addLink_task_main.setEnabled(true);
            addLink_smr_main.setEnabled(true);
            linkAction = (linkAction.equals("") ? "Добавить связь" : "Добавить/Изменить связь");
        }

        addLink_task_main.setText(linkAction.equals("") ? "Добавить связь" : linkAction);
        addLink_smr_main.setText(linkAction.equals("") ? "Добавить связь" : linkAction);
        projectStructureTree.repaint();
    }
    //endregion

    //endregion Блок. Методы подсветки работ и смет

    //region Блок. Методы работы со связями

    //region addLink() - добавление связей, вызов из
    private void addLink(ActionEvent evt) {

        ArrayList<SmetNode> smr = getSelectedSmr();
        ArrayList<ProjectNode> task = getSelectedTask();

        LTETableModel lteTableModel = new LTETableModel();
        LinkTableFrame linkTableFrame = new LinkTableFrame(linkTableArray, lteTableModel, smr, task, rsrcMap, curProject );
        linkTableFrame.start();

//        highlightTaskRows();

    }

    public void getDataAddLink() {
        long timeStart = System.currentTimeMillis();
        smetStructureTree.revalidate();

        linkTableArray.downloadFromSQL();
        long time = System.currentTimeMillis() - timeStart;
        System.out.println("linkTableArray.downloadFromSQL(): " + time);

        linkTM.setData(linkTableArray.getLinkArray());
        linkTable.setModel(linkTM);
        initLinkTable();
        linkTable.updateUI();

        highlightSmRows();
        time = System.currentTimeMillis() - timeStart;
        System.out.println("getDataAddLink(): " + time);
    }
    //endregion

    //region removeLinkFromMenu() - удаление связей из основных меню
    private void removeLinkFromMenu() {
        Object[] options = {"Удалить",
                "Отмена"};

        int choice = JOptionPane.showOptionDialog(this,
                "Вы уверены, что хотите удалить связи между выбранными работами и расценками?\n",
                "Удаление связи",
                JOptionPane.YES_NO_OPTION,
                JOptionPane.QUESTION_MESSAGE,
                null,
                options,
                options[0]);

        if (choice == 1) return;

        ArrayList<SmetNode> smrList = getSelectedSmr();
        ArrayList<ProjectNode> taskList = getSelectedTask();

        linkTableArray.removeLinks(smrList, taskList);

        if (projectStructureTree.getSelectedRowCount() > 0) {
            ProjectNode selNode = (ProjectNode) projectStructureTree.getPathForRow(projectStructureTree.getSelectedRow()).getLastPathComponent();
            if (selNode.isTask())
                updateRsrcTable(selNode.getRsrc());
        }

        smetStructureTree.repaint();
        taskRsrcTable.repaint();

        linkTableArray.downloadFromSQL();

        linkTM.setData(linkTableArray.getLinkArray());
        linkTable.setModel(linkTM);
        initLinkTable();
        linkTable.updateUI();


        isTaskUse(curProject);

        highlightSmRows();
        highlightTaskRows();
    }
    //endregion

    //region removeLink(ActionEvent evt) - Удаление связи из таблицы связей
    private void removeLink(ActionEvent evt) {
        Object[] options = {"Удалить",
                "Отмена"};

        int choice = JOptionPane.showOptionDialog(this,
                "Вы уверены, что хотите удалить связи между выбранными работами и расценками?\n",
                "Удаление связи",
                JOptionPane.YES_NO_OPTION,
                JOptionPane.QUESTION_MESSAGE,
                null,
                options,
                options[0]);

        if (choice == 1) return;

        ArrayList<SQLLink> selLinks = linkTM.getSelectedLinks(linkTable.getSelectedRows());

        ArrayList<SmetNode> smrList = new ArrayList<>();
        ArrayList<ProjectNode> taskList = new ArrayList<>();

        for (SQLLink link : selLinks) {
            if (smetStructureTreeModel.getRoot().getChildCount() > 0 && allSmrMap != null && allSmrMap.containsKey(link.getSmrMapId())) {
                smrList.add(allSmrMap.get(link.getSmrMapId()));
            }
            taskList.add(taskMap.get(link.getTaskId()));
        }

        linkTableArray.removeSelectedLinks(smrList, taskList, selLinks);

        if (projectStructureTree.getSelectedRowCount() > 0) {
            ProjectNode selNode = (ProjectNode) projectStructureTree.getPathForRow(projectStructureTree.getSelectedRow()).getLastPathComponent();
            if (selNode.isTask())
                updateRsrcTable(selNode.getRsrc());
        }

        smetStructureTree.repaint();
        taskRsrcTable.repaint();
        linkTable.repaint();
        projectStructureTree.repaint();

        isTaskUse(curProject);

        highlightSmRows();
        highlightTaskRows();

    }
    //endregion

    //region initArrayLink() - Инициализация массива связей открытого проекта
    private void initArrayLink() {
        linkTableArray = new LinkArray(curProject);
        linkTableArray.downloadFromSQL();
        smetStructureTreeModel.updateFact(linkTableArray.getLinkArray());
        smetStructureTree.repaint();
        initLinkTable();

    }
    //endregion

    //endregion Блок. Методы работы со связями

    public void projectStructureTreeSet(SQLProjectModel projectStructureModel) {
        projectStructureTree.setTreeTableModel(projectStructureModel);
        projectStructureTree.setRootVisible(true);
        projectStructureTree.updateUI();
    }

    //region openSQLProject(ActionEvent evt) - открытие формы, а затем и проекта из SQL, вызов из openProject_task_main, openProjectDlgBtn, jMenuItem7
    private void openSQLProject(ActionEvent evt) {

        op = new OpenProjectDialog(this, true, null);
        op.setVisible(true);

        if (op.curProject != null) {
            jMenuItem13.setEnabled(true);
            curProject = op.curProject;
            curProject.setParent(null);
            curProject.setIsTask(false);

            projectStructureModel = new SQLProjectModel();
            projectStructureModel.fill();
            projectStructureTree.setTreeTableModel(projectStructureModel);
            projectStructureTree.setRootVisible(true);

            projectStructureTree.updateUI();

            //Инициалицазия ArrayLink из SQL
            initArrayLink();
            isTaskUse(curProject);
            projectStructureTree.repaint();
            linkTM = new LinkTable (linkTableArray.getLinkArraySort("task"));
            linkTable.setModel(linkTM);

            ListSelectionModel selModel = linkTable.getSelectionModel();
            selModel.addListSelectionListener(new ListSelectionListener() {
                @Override
                public void valueChanged(ListSelectionEvent listSelectionEvent) {
                    if (!listSelectionEvent.getValueIsAdjusting() && linkTable.getSelectedRow() > 0) {
                        row = "";
                        row = String.valueOf(linkTM.getValueAt(linkTable.getSelectedRow(), 0));
                        linkTable.getColumnModel().getColumn(0).setCellRenderer(new CellRendererColorOther(row));
                        linkTable.getColumnModel().getColumn(1).setCellRenderer(new CellRendererTextArea(row));
                        linkTable.getColumnModel().getColumn(2).setCellRenderer(new CellRendererTextArea(row));
                        linkTable.getColumnModel().getColumn(3).setCellRenderer(new CellRendererColorOther(row));
                        linkTable.getColumnModel().getColumn(4).setCellRenderer(new CellRendererTextArea(row));
                        linkTable.getColumnModel().getColumn(5).setCellRenderer(new CellRendererColorOther(row));
                        linkTable.getColumnModel().getColumn(6).setCellRenderer(new CellRendererColorOther(row));
                        linkTable.getColumnModel().getColumn(7).setCellRenderer(new CellRendererColorFactor(row));
                        linkTable.getColumnModel().getColumn(8).setCellRenderer(new CellRendererColorFactor(row));
                        linkTable.getColumnModel().getColumn(9).setCellRenderer(new CellRendererColorCheckBox(row));
                    }
                    linkTable.updateUI();
                }
            });
            linkTable.getColumnModel().getColumn(0).setCellRenderer(new CellRendererColorOther(row));
            linkTable.getColumnModel().getColumn(1).setCellRenderer(new CellRendererTextArea(row));
            linkTable.getColumnModel().getColumn(2).setCellRenderer(new CellRendererTextArea(row));
            linkTable.getColumnModel().getColumn(3).setCellRenderer(new CellRendererColorOther(row));
            linkTable.getColumnModel().getColumn(4).setCellRenderer(new CellRendererTextArea(row));
            linkTable.getColumnModel().getColumn(5).setCellRenderer(new CellRendererColorOther(row));
            linkTable.getColumnModel().getColumn(6).setCellRenderer(new CellRendererColorOther(row));
            linkTable.getColumnModel().getColumn(7).setCellRenderer(new CellRendererColorFactor(row));
            linkTable.getColumnModel().getColumn(8).setCellRenderer(new CellRendererColorFactor(row));
            linkTable.getColumnModel().getColumn(9).setCellRenderer(new CellRendererColorCheckBox(row));
            linkTable.updateUI();
            initLinkTable();

            initProjectTree();
            jMenuItem8.setEnabled(true);
            jMenuItem10.setEnabled(true);
            jMenuItem11.setEnabled(true);
            jMenuItem12.setEnabled(true);
            jMenuItemExtendedReport.setEnabled(true);
        }
        projectConfig = new ProjectConfig(curProject.getId(), curProject.getDbName());
        projectConfig.loadConfig(curProject.getId(), curProject.getDbName());
    }
    //endregion

    //region openSmetDialog(ActionEvent evt) - Отображение фрейма открытия смет, вызов из
    private void openSmetDialog(ActionEvent evt) {
        centerOnScreen(openSmetDialog);

        OpenSQLSmet oss = new OpenSQLSmet();
        smetTree.setModel(new DefaultTreeModel(oss.open(), true));
        smetTree.updateUI();

        openSmetDialog.setVisible(true);
    }
    //endregion

    //region showSmetMenu(MouseEvent evt) - отображение высплывающего меню у дерева смет
    private void showSmetMenu(MouseEvent evt) {
        if (evt.isPopupTrigger()) {
            menu_smr_main.show(smetStructureTree, evt.getX(), evt.getY());

            searchTask_task_main.setEnabled(false);
            if (curProject!= null) {
                searchTask_task_main.setEnabled(true);
            }
        }
    }
    //endregion

    //region showProjectMenu(MouseEvent evt) - отображение всплывающего меню у дерева проектов
    private void showProjectMenu(MouseEvent evt) {
        if (evt.isPopupTrigger()) {
            menu_task_main.show( projectStructureTree, evt.getX(), evt.getY() );
        }

        Point p = evt.getPoint();
        if (evt.getClickCount() == 2) {
            int row = projectStructureTree.rowAtPoint(p);
            ProjectNode projectNodeRow = (ProjectNode) projectStructureTree.getPathForRow(row).getLastPathComponent();
            int childCount = projectStructureModel.getChildCount(projectNodeRow);
            boolean isNextChild = false;
            int treeRowCount = projectStructureTree.getRowCount()-1;
            if (row != 0) {
                if (row != treeRowCount) {
                    ProjectNode projectNodeRowChild = (ProjectNode) projectStructureTree.getPathForRow(row+1).getLastPathComponent();
                    if (projectNodeRowChild.getParentId() == projectNodeRow.getId()) {
                        isNextChild = true;
                    }
                    if (isNextChild == false) {
                        if (childCount != 0) {
                            expandNodeProject(projectStructureTree, row, childCount);
                        }
                    } else {
                        if (childCount != 0) {
                            collapseNode(projectStructureTree, row, childCount);
                        }
                    }
                } else {
                    if (isNextChild == false) {
                        if (childCount != 0) {
                            expandNodeProject(projectStructureTree, row, childCount);
                        }
                    } else {
                        if (childCount != 0) {
                            collapseNode(projectStructureTree, row, childCount);
                        }
                    }
                }

            } else {
                if (projectStructureTree.getPathForRow(row+1) != null) {
                    collapseTree(projectStructureTree);
                } else {
                    expandTree(projectStructureTree);
                }
            }
        }
    }
    //endregion

    private void checkSelectedRows() {
        //checking selected rows in smetStructureTree
        Boolean smetSel = false; // flag

        int[] selRows = smetStructureTree.getSelectedRows();

        for ( int i = 0; i < smetStructureTree.getSelectedRowCount(); i++ ) {
            SmetNode selNode = (SmetNode) smetStructureTree.getPathForRow(selRows[i]).getLastPathComponent();

            if ( selNode.isHeader ) closeSmet_smr_main.setEnabled(true);

            if (selNode.isString) {
                smetSel = true;
                break;
            }
        }
        selRows = projectStructureTree.getSelectedRows();

        for (int j = 0; j < projectStructureTree.getSelectedRowCount(); j++) {
            ProjectNode selNode = (ProjectNode) projectStructureTree.getPathForRow(selRows[j]).getLastPathComponent();
            if ( selNode.isTask() ) {
                toggleFilter_task_main.setEnabled(true);
                if (smetSel) {
                    addLink_smr_main.setEnabled(true);
                    addLink_task_main.setEnabled(true);
                    addLink_smr_main.setText("Добавить связь");
                    addLink_task_main.setText("Добавить связь");
                }
                break;
            }
        }

    }

    private ArrayList<SmetNode> getSelectedSmr () {

        ArrayList <SmetNode> smrs = new ArrayList<SmetNode>();
        int[] selRows = smetStructureTree.getSelectedRows();

        for ( int i = 0; i < smetStructureTree.getSelectedRowCount(); i++ )
        {
            SmetNode selNode = (SmetNode) smetStructureTree.getPathForRow(selRows[i]).getLastPathComponent();

            if (selNode.isString) smrs.add( selNode );
        }

        return smrs;

    }

    private ArrayList<ProjectNode> getSelectedTask () {

        ArrayList <ProjectNode> tasks = new ArrayList<ProjectNode>();
        int[] selRows = projectStructureTree.getSelectedRows();

        for (int j = 0; j < projectStructureTree.getSelectedRowCount(); j++)
        {
            ProjectNode selNode = (ProjectNode) projectStructureTree.getPathForRow(selRows[j]).getLastPathComponent();
            if ( selNode.isTask() ) tasks.add( selNode );
        }

        return tasks;

    }

    //region toggleTaskFilter(ActionEvent evt) - Включение или выключение фильтра работ
    private void toggleTaskFilter(ActionEvent evt) {
        if (linkTableArray.getFilter()) {
            System.out.println("getFilter = true");
            linkTM.setData(linkTableArray.getLinkArray());
            linkTableArray.setFilter (false);
            toggleFilter_task_main.setText("Установить фильтр");
            filterTaskPanel.removeFilter();
        } else {
            System.out.println("getFilter = false");
            toggleFilter_task_main.setText("Убрать фильтр");
            linkTM.setData(linkTableArray.setTaskFilter(getSelectedTask()));
            filterTaskPanel.setFilterHead(getSelectedTask(), linkTM, linkTable, linkTableArray, linkFrame);
            linkFrame.setVisible(true);
        }
        linkTable.repaint();
     }
    //endregion

    private void addTaskToFilter() {
        ArrayList<ProjectNode> tempSmet;
        boolean flag;
        tempSmet = filterTaskPanel.filterList;
        for (ProjectNode tempNode : getSelectedTask()) {
            flag = true;
            for (ProjectNode fl : filterTaskPanel.filterList) {
                if (tempNode.getId() == fl.getId()) {
                    flag = false;
                }
            }
            if (flag) {
                tempSmet.add(tempNode);
            }
        }
        linkTM.setData(linkTableArray.setTaskFilter(tempSmet));
        filterTaskPanel.setFilterHead(tempSmet, linkTM, linkTable, linkTableArray, linkFrame);
        linkFrame.setVisible(true);
    }

    private void openSumDataTableDlg (String type) {
        SelectProjectDialog selectProjectDialog = new SelectProjectDialog(this, connSQL, type);
        selectProjectDialog.setVisible(true);
    }

    private void open_smetDlg(ActionEvent evt) {

        int[] ks = smetTree.getSelectionRows();

        for (int k : ks) {
            SmetNode node = (SmetNode) smetTree.getPathForRow(k).getLastPathComponent();
            if (node == null || !node.isString)
                continue;

            smetStructureTreeModel.openSmet(node);
        }
        openSmetDialog.setVisible(false);
        initLinkTable();
        if (linkTableArray != null) {
            smetStructureTreeModel.updateFact(linkTableArray.getLinkArray());
            smetStructureTree.repaint();
        }
        smetStructureTree.updateUI();
        highlightSmRows();
    }

    private void cancel_smetDlg(ActionEvent evt) { openSmetDialog.setVisible(false); }

    private void sortLink(String from) {
        linkTM = null;
        linkTM = new LinkTable(linkTableArray.getLinkArraySort(from));
        linkTable.revalidate();
        linkTable.validate();
    }

    //region expandTree(JXTreeTable tree) - Раскрыть все дерево
    public void expandTree(JXTreeTable tree) {
        int row = 0;
        while (row < tree.getRowCount()) {
            tree.expandRow(row);
            row++;
        }
    }
    //endregion

    //region collapseTree(JXTreeTable tree) - Свернуть все дерево
    public void collapseTree(JXTreeTable tree) {
        int row = tree.getRowCount() - 1;
        while (row >= 0) {
            tree.collapseRow(row);
            row--;
        }
    }
    //endregion

    public void expandNode(JXTreeTable tree,int rrow, int nodeRow) {
        int row = rrow;
        SmetNode smetNodeRow1 = (SmetNode) smetStructureTree.getPathForRow(row).getLastPathComponent();
        tree.expandPath(tree.getPathForRow(row));
        if (smetNodeRow1.getChildCount() != 0) {
            for (int i = smetNodeRow1.getChildCount(); i > 0; i--) {
                tree.expandPath(tree.getPathForRow(row+i+1));
            }
        }
    }

    public void expandNodeProject(JXTreeTable tree,int rrow, int nodeRow) {
        int row = rrow;
        ProjectNode workNodeRow1 = (ProjectNode) projectStructureTree.getPathForRow(row).getLastPathComponent();
        tree.expandPath(tree.getPathForRow(row));
        if (workNodeRow1.getChildCount() != 0) {
            for (int i = workNodeRow1.getChildCount(); i > 0; i--) {
                tree.expandPath(tree.getPathForRow(row+i));
            }
        }
    }

    public void collapseNode(JXTreeTable tree,int rrow, int nodeRow) {
        int row = rrow;
        int howMuchRow = nodeRow + row;
        while (howMuchRow >= row) {
            tree.collapseRow(howMuchRow);
            howMuchRow--;
        }
    }

    private void updateRsrcTable(ArrayList<SQLTaskRsrc> list) {
        Object[][] tableData = new Object[list.size()][5];
        Integer i = 0;

        if (list.size() > 0 ) {
            for (SQLTaskRsrc cur : list) {
                tableData[i] = new Object[]{cur.getRsrcShortName(), cur.getRsrcName(), cur.getPlannedUnits(), cur.getRsrcType()};
                i++;
            }
        } else {
            tableData = new Object[1][5];
            tableData[0] = new Object[]{null, "Нет назначений ресурсов", null, null};
        }
        taskRsrcTable.setModel(new DefaultTableModel((tableData.length != 0) ? tableData : null, colNames));
        taskRsrcTable.putClientProperty("JTable.autoStartsEdit", Boolean.FALSE);
        taskRsrcTable.getColumn(taskRsrcTable.getColumnName(2)).setCellRenderer(taskRsrcTable.getDefaultRenderer(Double.class));
        initTaskRsrcTable();
        taskRsrcTable.updateUI();
    }

    private ArrayList <SQLLink> getSqlSmets() {
        ArrayList <SQLLink> smrs = new ArrayList <SQLLink>();

        try {

            this.connSQL = MsSQLConnect.ConnectDB("TST");

            CallableStatement stmt = connSQL.prepareCall("{call getSmrs()}");
            ResultSet rs = stmt.executeQuery();

//            while (rs.next()) {
//                if (rs.getString("smetNumber") != null && !rs.getString("smetNumber").equals(""))
//                    smrs.add( new SmetNode ( rs.getString("smrName"), rs.getInt(1), rs.getString(3), rs.getString(4), rs.getDouble(5), rs.getDouble(6), rs.getDouble(7), rs.getDouble(8), true, rs.getInt(9), smh.getName() ) );
//            }

            rs.close();
            stmt.close();

            connSQL.close();
        } catch (SQLException e) {
            e.printStackTrace();
        }
        return smrs;
    }

    //region Поиск работы по номеру или названию
    private void findTask() {

        Enumeration e = curProject.breadthFirstEnumeration();
        while (e.hasMoreElements()) {
        ProjectNode node = (ProjectNode) e.nextElement();
            if (node.getShortName().toLowerCase().contains(taskFindName.toLowerCase()) || node.getName().toLowerCase().contains(taskFindName.toLowerCase())) {
                TreeNode[] nodes = node.getPath();
                TreePath path = new TreePath(nodes);
                projectStructureTree.scrollPathToVisible(path);
                if (findRow != 0) {
                    if (findRow == projectStructureTree.getRowForPath(path)) {
                        findRow = 0;
                    }
                } else {
                    findRow = projectStructureTree.getRowForPath(path);
                }
            }
        }
        if (findRow == 0) {
            JOptionPane.showMessageDialog(null, "Работа не найдена!");
        } else {
            projectStructureTree.scrollRowToVisible(findRow);
            projectStructureTree.setRowSelectionInterval(findRow, findRow);
        }
    }
    //endregion

    //region showMeLink() - Поиск сметных строк по работе
    private void showMeLink() {
        HashMap<Integer, Integer> hashSmetSearch = new HashMap<>();
        ArrayList<Integer> listSmetSearch = new ArrayList<>();
        for (ProjectNode node : getSelectedTask()) {
            for (SQLLink link : linkTableArray.getLinkArray()) {
                if (link.getTaskId() == node.getId()) {
                    hashSmetSearch.put(link.getSmrId(), link.getSmrId());
                }
            }
        }
        listSmetSearch.addAll(hashSmetSearch.values());
        findNotOpenSmet(listSmetSearch, hashSmetSearch);
        for (Integer id : listSmetSearch) {
            Enumeration e = smetStructureTreeModel.getRoot().breadthFirstEnumeration();
            while (e.hasMoreElements()) {
                SmetNode smet = (SmetNode) e.nextElement();
                if (smet.getId() == id) {
                    TreeNode[] nodes = smet.getPath();
                    TreePath path = new TreePath(nodes);
                    smetStructureTree.scrollPathToVisible(path);
                }
            }
        }
    }
    //endregion


    //region findNotOpenSmet(ArrayList<Integer> listSmetSearch, HashMap<Integer, Integer> hashSmetSearch) - Поиск смет не открытых в Factage
    private void findNotOpenSmet(ArrayList<Integer> listSmetSearch, HashMap<Integer, Integer> hashSmetSearch) {
        HashMap<Integer, Integer> listOpenSmet = new HashMap<>();
        if (smetStructureTreeModel.getRoot().getChildCount() > 0) {
            for (SmetNode sm : smetStructureTreeModel.getRoot().getChildren()) {
                listOpenSmet.put(sm.getId(), sm.getId());
            }
        }

        SearchSmet searchSmet = new SearchSmet(listSmetSearch, hashSmetSearch, listOpenSmet);

        SmetNode findSmet = searchSmet.search();
        if (findSmet.getChildCount() > 0) {
            centerOnScreen(openSmetDialog);

            smetTree.setModel(new DefaultTreeModel(findSmet, true));
            smetTree.updateUI();

            openSmetDialog.setVisible(true);
        }
    }
    //endregion

    //region Блок. Загрузка назначений ресурсов из XLS-файла
//    private void parseLinkFile (File file) {
//        FileInputStream fileInputStream = null;
//
//        Boolean omgFlag = false;
//
//        ArrayList <SQLLink> links = new ArrayList <SQLLink> ();
//        ArrayList<SmetNode> smrs = new ArrayList<SmetNode>();
//
//        this.connSQL = MsSQLConnect.ConnectDB ("TST");
//        try {
//            CallableStatement stmt = connSQL.prepareCall("{call [getSmrs]()}");
//            ResultSet rs = stmt.executeQuery();
//
//            while (rs.next()) {
//                if (rs.getString(1) != null && rs.getString(1) != ""){
//                    SmetNode sm = new SmetNode(rs.getString(2), rs.getInt(3), rs.getString(4), rs.getString(5), rs.getDouble(6), rs.getDouble(7), rs.getDouble(8), rs.getDouble(9), true, rs.getInt(10), rs.getString(1));
//                    Double K = sm.getVolume();
//                    if (sm.getUnit() != null && sm.getUnit().length() > 3) {
//                        String sup = sm.getUnit().substring(0,4);
//                        if (sup.contains("1000")) {
//                            K *= 1000;
//                        } else if (sup.contains("100")) {
//                            K *= 100;
//                        } else if (sup.contains("10")) {
//                            K *= 10;
//                        }
//                    }
//                    sm.setFactor(0.0);
//                    sm.setFactorFull(K);
//                    smrs.add(sm);
//                }
//            }
//
//            connSQL.close();
//        } catch (SQLException e) {
//            e.printStackTrace();
//        }
//
//        try {
//            fileInputStream = new FileInputStream(file);
//
//            BufferedReader reader = null;
//
//            reader = new BufferedReader(new InputStreamReader(fileInputStream, "UTF-8"));
//
//            tasks = getSqlProject();
//
//            while (true) {
//                String line = reader.readLine();
//                if (line == null) break;
//                String[] fields = line.split(";");
//                Boolean stringDone = false;
//                for (int i = 2; i<fields.length; i++) {
//                    if (stringDone) break;
//                    String[] smrTitul = fields[i].split("-");
//                    for (SmetNode sm : smrs) {
//                        if (sm.getSmNum().contains(smrTitul[0]) && smrTitul[1].equals(sm.getNum()) && sm.getFactor() < sm.getFactorFull()) {
//
//                            Double pvVol = sm.getVolume() * Double.valueOf(fields[1])/sm.getFactorFull();
//                            SQLLink link = new SQLLink(0, "", tasks.get(fields[0]).getShortName(), tasks.get(fields[0]).getName(), sm.getNum(), sm.getName(), sm.getVolume(), Double.valueOf(fields[1]), sm.getFactorFull(), sm.getName().contains("Трубопровод"), tasks.get(fields[0]).getId(), sm.getId(), sm.getSmNum(), pvVol, sm.getUnit());
//                            link.setMechVol(sm.getMR() * link.getFact() / link.getFactFull());
//                            link.setTVol(sm.getHR() * link.getFact()/link.getFactFull());
//                            link.setMrVol(sm.getCost() * link.getFact() / link.getFactFull());
//                            link.setDbName(curProject.getDbName());
//                            link.setProjectId(curProject.getId());
//                            sm.setFactor(Double.valueOf(fields[1]) + sm.getFactor());
//                            stringDone = true;
//
//                            for (SQLLink lenk : links) {
//                                if (lenk.getSmrId() == link.getSmrId() && lenk.getTaskId() == link.getTaskId()) {
//                                    if (lenk.getPv()) lenk.setPvVol(lenk.getPvVol() + sm.getVolume() * link.getFact()/link.getFactFull());
//                                    lenk.setMechVol(lenk.getMechVol() + sm.getMR() * link.getFact() / link.getFactFull());
//                                    lenk.setTVol(lenk.getTVol() + sm.getHR() * link.getFact()/link.getFactFull());
//                                    lenk.setMrVol(lenk.getMrVol() + sm.getCost() * link.getFact() / link.getFactFull());
//                                    lenk.setFact(lenk.getFact() + Double.valueOf(fields[1]));
//                                    sm.setFactor(Double.valueOf(fields[1]) + sm.getFactor());
//
//                                    omgFlag = true;
//                                    stringDone = true;
//                                }
//                            }
//
//                            if (omgFlag == false) {
//                                links.add(link);
//                            }
//                        }
//                    }
//                }
//            }
//            reader.close();
//
//        } catch (IOException e) {
//            e.printStackTrace();
//        }
//        LinkTableFrame linkTableFrame = new LinkTableFrame(links, curProject, getAllTask(), rsrcMap);
//        linkTableFrame.addExcelLinks();
//    }

    private HashMap<String, ProjectNode> getSqlProject() {

        HashMap<String, ProjectNode> projMap = new HashMap<String, ProjectNode>();

        try {

            this.connSQL = MsSQLConnect.ConnectDB("Factage");

            CallableStatement stmt = connSQL.prepareCall( "{call getTask(?, ?)}" );
            stmt.setString( 1, curProject.getDbName() );
            stmt.setInt( 2, curProject.getId() );
            ResultSet rs = stmt.executeQuery();

            while ( rs.next() ) {
                ProjectNode task = new ProjectNode( rs.getString( "task_name" ), rs.getString( "task_code" ), rs.getInt( "task_id" ), rs.getInt( "wbs_id" ),
                        true, rs.getDouble( "task_complete_pct" ) , rs.getString("act_code_value"), rs.getDate("actual_start_date"), rs.getDate("actual_finish_date") );
                task.setPvValue(rs.getString( "pv_value" ));
                task.setUomValue(rs.getString( "uom_value" ));
                projMap.put(rs.getString( "task_code" ), task);
            }

            rs.close();
            stmt.close();
            connSQL.close();

        } catch ( SQLException e ) {
            e.printStackTrace();
        }

        return projMap;
    }

    //region getAllTask() - возвращает список работ, вызов из ParseLinkFile()
    private ArrayList<ProjectNode> getAllTask() {
        ArrayList<ProjectNode> tasks = new ArrayList<ProjectNode>();
        recursion(curProject, tasks);
        return tasks;
    }
    //endregion

    //region recursion(ProjectNode node, ArrayList<ProjectNode> tasks) - рекурсия, возвращает список работ, вызов из getAllTask()
    private void recursion (ProjectNode node, ArrayList<ProjectNode> tasks) {
        if (node.getChildren() != null && node.getChildCount() > 0) {
            for (ProjectNode nod : node.getChildren()) {
                recursion (nod, tasks);
            }
        } else {
            if (node.isTask()) tasks.add(node);
        }
    }
    //endregion

    //endregion

    //region Блок. функции проверки связей - не используются
    /**temp correction function*/
    private void checkLinkshours () {
        HashMap<Integer, SmetNode> hashMap = new HashMap<>();
        try {
            this.connSQL = MsSQLConnect.ConnectDB("Factage"); ;

            Statement stmt = connSQL.createStatement();
            ResultSet rs = stmt.executeQuery("SELECT smr_id, smrNumber, smrName, smrUnit, smrQuantity, smrTotalDirectCost, smrTotalLabourCost, smrTotalLabourMashCost, sect_id FROM ks_Sm_rows");

            System.out.println("3");
            while (rs.next()) {
                hashMap.put(rs.getInt(1), new SmetNode(rs.getString(2), rs.getInt(1), rs.getString(3), rs.getString(4), rs.getDouble(5), rs.getDouble(6), rs.getDouble(7), rs.getDouble(8), true, rs.getInt(9), ""));
            }

            rs.close();
            stmt.close();

            this.connSQL.close();

        } catch (SQLException e) {
            e.printStackTrace();
        }

    }

    /**temp correction function*/
//    private void checkLinks () {
//        System.out.println("2");
//        HashMap<Integer, SmetNode> hashMap = new HashMap<>();
//        try {
//            this.connSQL = MsSQLConnect.ConnectDB("Factage"); ;
//
//            Statement stmt = connSQL.createStatement();
//            ResultSet rs = stmt.executeQuery("SELECT smr_id, smrNumber, smrName, smrUnit, smrQuantity, smrTotalDirectCost, smrTotalLabourCost, smrTotalLabourMashCost, sect_id FROM ks_Sm_rows");
//
//            while (rs.next()) {
//                hashMap.put(rs.getInt(1), new SmetNode(rs.getString(2), rs.getInt(1), rs.getString(3), rs.getString(4), rs.getDouble(5), rs.getDouble(6), rs.getDouble(7), rs.getDouble(8), true, rs.getInt(9), ""));
//            }
//
//            System.out.println("4");
//            for (SQLLink link : linkTableArray.getLinkArray() ) {
//                System.out.println("5");
//                SmetNode smr = hashMap.get(link.getSmrId());
//                if (link.getMechVol() == smr.getMR() * link.getFact()/link.getFactFull()) continue;
//
//                Double oldPvVol = link.getPvVol();
//                Double oldMrVol = link.getMrVol();
//                Double oldTVol = link.getTVol();
//                Double oldMechVol = link.getMechVol();
//
//                if (link.getPv()) link.setPvVol(smr.getVolume() * link.getFact()/link.getFactFull());
//                link.setMechVol(smr.getMR() * link.getFact() / link.getFactFull());
//                link.setTVol(smr.getHR() * link.getFact() / link.getFactFull());
//                link.setMrVol(smr.getCost() * link.getFact()/link.getFactFull());
//
//                ProjectNode task = new SQLProjectModel().getTask(link.getTaskId(), curProject);
//                if (link.getPv() && !task.getTaskCodeValue().equals(""))
//                    checkRsrc(task, task.getTaskCodeValue(), link.getPvVol() - oldPvVol);
//
//                checkFFRsrc(task, "MECH", link.getMechVol() - oldMechVol);
//                checkFFRsrc(task, "T", link.getTVol() - oldTVol);
//                checkFFRsrc(task, "MR", link.getMrVol() - oldMrVol);
//                link.updateSQL(connSQL);
//            }
//
//            this.connSQL.close();
//
//        } catch (SQLException e) {
//            e.printStackTrace();
//        }
//
//
//    }

    /**temp correction function*/
    private void checkRsrc(ProjectNode task, String rsrShortName, Double plannedUnits) {
        for (SQLTaskRsrc tr : task.getRsrc()) {

            if (tr.getRsrcShortName().equals(rsrShortName)) {
                Double units = tr.getPlannedUnits();
                tr.setPlannedUnits(plannedUnits + units);
                tr.updateSQL();
                if (plannedUnits + units < 0.001) task.getRsrc().remove(tr);
                return;
            }
        }

        if (plannedUnits > 0.001) {
            SQLRsrc rsr = rsrcMap.get(rsrShortName);
            SQLTaskRsrc tr = new SQLTaskRsrc(0, task.getId(), rsr.getRsrcId(), 0, rsr.getRsrcName(), rsr.getRsrcType(), rsr.getRsrcShortName(), plannedUnits, "", curProject.getDbName(), curProject.getId());
            tr.updateSQL();
            task.getRsrc().add(tr);
        }
    }

    /**temp correction function*/
    private void checkFFRsrc(ProjectNode task, String rsrShortName, Double plannedUnits) {
        for (SQLTaskRsrc tr : task.getRsrc()) {
            if (tr.getRsrcShortName().equals(rsrShortName)) {
                Double units = tr.getPlannedUnits();
                tr.setPlannedUnits(plannedUnits + units);
                tr.updateSQL();
                if (plannedUnits + units < 0.001) task.getRsrc().remove(tr);
                return;
            }
        }
    }
    //endregion

    //region foundTask() - Диалог поиска работы по коду или названию

    private JTextField taskName;
    private JButton found, cancel;
    private JPanel panel;
    private JLabel label;
    private String task;
    private JDialog dialog;

    public void foundTask() {
        findRow = 0;
        dialog = new JDialog();
        task = "";
        setTitle("Поиск работы");
//        setModal(true);
        taskName = new JTextField();
        taskName.addActionListener(new ActionListener() {
            @Override
            public void actionPerformed(ActionEvent actionEvent) {
                taskFindName = taskName.getText();
                findTask();
            }
        });
        found = new JButton("Найти");
        found.addActionListener(new ActionListener() {
            @Override
            public void actionPerformed(ActionEvent actionEvent) {
                taskFindName = taskName.getText();
                findTask();
            }
        });
        cancel = new JButton("Отмена");
        cancel.addActionListener(new ActionListener() {
            @Override
            public void actionPerformed(ActionEvent actionEvent) {
                taskName.setText("");
                dialog.setVisible(false);
            }
        });
        panel = new JPanel();
        label = new JLabel("Введите название работы:");
        int width = 200;
        int height = 150;
        dialog.setSize(new Dimension(width, height));
        Dimension screensize = Toolkit.getDefaultToolkit().getScreenSize();
        dialog.setLocation(screensize.width / 2 - width / 2, screensize.height / 2 - height / 2);

        GridBagConstraints c;
        panel.setLayout(new GridBagLayout());

        c = new GridBagConstraints();
        c.gridx = 0;
        c.gridy = 0;
        c.gridwidth = 2;
        c.insets = new Insets(15, 15, 5, 15);
        c.anchor = GridBagConstraints.EAST;
        c.fill = GridBagConstraints.HORIZONTAL;
        panel.add(label, c);

        c = new GridBagConstraints();
        c.gridx = 0;
        c.gridy = 1;
        c.gridwidth = 2;
        c.insets = new Insets(0, 15, 25, 15);
        c.anchor = GridBagConstraints.EAST;
        c.weightx = 1;
        c.fill = GridBagConstraints.HORIZONTAL;
        panel.add(taskName, c);

        c = new GridBagConstraints();
        c.gridx = 0;
        c.gridy = 2;
        c.insets = new Insets(0, 15, 5, 0);
        c.anchor = GridBagConstraints.EAST;
        c.fill = GridBagConstraints.HORIZONTAL;
        panel.add(found, c);

        c = new GridBagConstraints();
        c.gridx = 1;
        c.gridy = 2;
        c.insets = new Insets(0, 20, 5, 15);
        c.anchor = GridBagConstraints.EAST;
        c.fill = GridBagConstraints.HORIZONTAL;
        panel.add(cancel, c);

        dialog.add(panel);
        dialog.setVisible(true);
    }
    //endregion

    //region searchTask() - Метод поиска работы по коду или названию
    private void searchTask() {
        HashMap<Integer, Integer> hashTaskSearch = new HashMap<>();
        ArrayList<Integer> listTaskSearch = new ArrayList<>();
        for (SmetNode sm : getSelectedSmr()) {
            for (SQLLink link : linkTableArray.getLinkArray()) {
                if (link.getSmrId() == sm.getId()) {
                    hashTaskSearch.put(link.getTaskId(), link.getTaskId());
                }
            }
        }
        listTaskSearch.addAll(hashTaskSearch.values());
        for (Integer id : listTaskSearch) {
            Enumeration e = curProject.breadthFirstEnumeration();
            while (e.hasMoreElements()) {
                ProjectNode node = (ProjectNode) e.nextElement();
                if (node.getId() == id) {
                    TreeNode[] nodes = node.getPath();
                    TreePath path = new TreePath(nodes);
                    projectStructureTree.scrollPathToVisible(path);
                    if (findRow != 0) {
                        if (findRow == projectStructureTree.getRowForPath(path)) {
                            findRow = 0;
                        }
                    } else {
                        findRow = projectStructureTree.getRowForPath(path);
                    }
                }
            }
                projectStructureTree.scrollRowToVisible(findRow);
        }
    }
    //endregion

    public javax.swing.JButton addLinkButton, cancelAddLinkButton, cancelOpenSmetButton, loginPrimaveraButton, openProjectDlgBtn, openSmetButton, openSmetDialogButton, showLinkFrameButton, synchButton, validButton, sortTaskButton, sortSmetButton, linkXMLButton, checkLinksButton, ksFormButton, skFormButton, importSmet, loadExcelLinks, xlsLinkSmet, lockProjectButton, updateRaButton;
    private javax.swing.JDialog addLinkDialog;
    private javax.swing.JMenuBar jMenuBar1;
    private javax.swing.JMenu jMenu1, jMenu2, jMenu5, jMenuConfig;
    private javax.swing.JMenuItem  deleteLink,  jMenuItem7, jMenuItem8, jMenuItem9, jMenuItem10, jMenuItem11, jMenuItem12, jMenuItem13, jMenuItemExtendedReport, jMenuItemMatrixReportTask, jMenuItemMatrixReportSmet, jMenuItemConfig;

    //region Контекстное меню для дерева смет
    private JPopupMenu menu_smr_main;
    private JMenuItem searchTaskFromSmet_smr_main, addLink_smr_main, removeLink_smr_main, openSmet_smr_main, closeSmet_smr_main;
    //endregion

    //region Контекстное меню для дерева работ
    private JPopupMenu menu_task_main;
    private JMenuItem addLink_task_main, openProject_task_main,  toggleFilter_task_main, addToFilter_task_main, searchTask_task_main, removeLink_task_main,  showLinkedSmet_task_main;
    //endregion

    private javax.swing.JTable addLinkTable, linkTable;
    private javax.swing.JLabel jLabel1, jLabel2, jLabel3, jLabel4, jLabel5, jLabel6;
    private javax.swing.JPanel jPanel1, jPanel2, jPanel3, panelFilterTask;
    private javax.swing.JScrollPane jScrollPane1, jScrollPane2, jScrollPane3, jScrollPane4, jScrollPane5, jScrollPane6, jScrollPane7;
    private javax.swing.JToolBar.Separator jSeparator1, jSeparator2, jSeparator3;
    private javax.swing.JSeparator jSeparator7, jSeparator6, jSeparator9;
    private javax.swing.JSplitPane jSplitPane1;
    private javax.swing.JToolBar jToolBar2, jToolBar3, primaveraToolBar, linkBar;
    private StatusBar  statusBar;
    private javax.swing.JFrame linkFrame;
    private javax.swing.JDialog openSmetDialog;
    private JPopupMenu menu_linkFrame;
    private org.jdesktop.swingx.JXTreeTable projectStructureTree, smetStructureTree;
    private javax.swing.JTable taskRsrcTable;
    private javax.swing.JTree smetTree;
    private String taskFindName;
    private boolean expand_collapse = false;
    private ArrayList<ProjectNode> listForSearch;
    private FilterTaskPanel filterTaskPanel;

}